sta*_*ion 6 mongodb pymongo mongodb-query aggregation-framework
我有一个mongodb系列.当我做.
db.bill.find({})
Run Code Online (Sandbox Code Playgroud)
我明白了
{
"_id" : ObjectId("55695ea145e8a960bef8b87a"),
"name" : "ABC. Net",
"code" : "1-98tfv",
"abbreviation" : "ABC",
"bill_codes" : [ 190215, 44124, 190215, 147708 ],
"customer_name" : "abc"
}
Run Code Online (Sandbox Code Playgroud)
我需要一个操作来从bill_codes中删除重复的值.最后它应该是
{
"_id" : ObjectId("55695ea145e8a960bef8b87a"),
"name" : "ABC. Net",
"code" : "1-98tfv",
"abbreviation" : "ABC",
"bill_codes" : [ 190215, 44124, 147708 ],
"customer_name" : "abc"
}
Run Code Online (Sandbox Code Playgroud)
如何在mongodb中实现这一目标.
小智 16
那你可以使用聚合框架做到这一点,如下所示:
collection.aggregate([
{ "$project": {
"name": 1,
"code": 1,
"abbreviation": 1,
"bill_codes": { "$setUnion": [ "$bill_codes", [] ] }
}}
])
Run Code Online (Sandbox Code Playgroud)
该$setUnion
运营商是一个"套"操作,因此做一个"套",则只有"唯一"的项目被保留后面.
如果你还在使用MongoDB的版本比2.6更旧,那么你就必须做这个操作与$unwind
和$addToSet
替代:
collection.aggregate([
{ "$unwind": "$bill_codes" },
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"code": { "$first": "$code" },
"abbreviation": { "$first": "$abbreviation" },
"bill_codes": { "$addToSet": "$bill_codes" }
}}
])
Run Code Online (Sandbox Code Playgroud)
它没有那么高效,但自2.2版以来就支持运营商.
当然,如果您确实要永久修改收集文档,则可以对此进行扩展并相应地处理每个文档的更新.您可以从中检索"光标" .aggregate()
,但基本上遵循以下shell示例:
db.collection.aggregate([
{ "$project": {
"bill_codes": { "$setUnion": [ "$bill_codes", [] ] },
"same": { "$eq": [
{ "$size": "$bill_codes" },
{ "$size": { "$setUnion": [ "$bill_codes", [] ] } }
]}
}},
{ "$match": { "same": false } }
]).forEach(function(doc) {
db.collection.update(
{ "_id": doc._id },
{ "$set": { "bill_codes": doc.bill_codes } }
)
})
Run Code Online (Sandbox Code Playgroud)
早期版本更多涉及:
db.collection.aggregate([
{ "$unwind": "$bill_codes" },
{ "$group": {
"_id": {
"_id": "$_id",
"bill_code": "$bill_codes"
},
"origSize": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id._id",
"bill_codes": { "$push": "$_id.bill_code" },
"origSize": { "$sum": "$origSize" },
"newSize": { "$sum": 1 }
}},
{ "$project": {
"bill_codes": 1,
"same": { "$eq": [ "$origSize", "$newSize" ] }
}},
{ "$match": { "same": false } }
]).forEach(function(doc) {
db.collection.update(
{ "_id": doc._id },
{ "$set": { "bill_codes": doc.bill_codes } }
)
})
Run Code Online (Sandbox Code Playgroud)
使用添加的操作来比较"重复数据删除"数组是否与原始数组长度相同,并且只返回那些已删除"重复"的文档以便在更新时进行处理.
也许应该在这里添加"for python"注释.如果你不关心"识别"包含重复数组条目的文档并准备用更新"爆炸"整个集合,那么只需.set()
在客户端代码中使用python 来删除重复项:
for doc in collection.find():
collection.update(
{ "_id": doc["_id"] },
{ "$set": { "bill_codes": list(set(doc["bill_codes"])) } }
)
Run Code Online (Sandbox Code Playgroud)
所以这很简单,它取决于哪个是更大的邪恶,找到带有重复的文件或更新每个文件的成本是否需要它.
这至少涵盖了技术.
归档时间: |
|
查看次数: |
5378 次 |
最近记录: |