如何更新mongodb中字段具有相同值的文档?

时间:2017-03-02 08:03:45

标签: javascript mongodb

我有

{ "_id" : ObjectId("58b713280000000000000000"), "role" : "admin", "clientId" : ObjectId("598231980000000000000000")},
{ "_id" : ObjectId("58dff1a80000000000000000"), "role" : "user", "clientId" : ObjectId("598231980000000000000000")},
{ "_id" : ObjectId("59077ea80000000000000000"), "role" : "user", "clientId" : ObjectId("598231980000000000000000")},
{ "_id" : ObjectId("59305d280000000000000000"),"role" : "user", "clientId" : ObjectId("598231980000000000000000")},
{ "_id" : ObjectId("5957ea280000000000000000"),"role" : "user", "clientId" : ObjectId("598231980000000000000000")},
{ "_id" : ObjectId("59593ba80000000000000000"), "role" : "admin", "clientId" : ObjectId("598b6c180000000000000000")},
{ "_id" : ObjectId("59821a280000000000000000"),"role" : "user", "clientId" : ObjectId("598b6c180000000000000000")},
{ "_id" : ObjectId("598228380000000000000000"),"role" : "user", "clientId" : ObjectId("598b6c180000000000000000")},
{ "_id" : ObjectId("598227fc0000000000000000"),"role" : "user", "clientId" : ObjectId("598b6c1d0000000000000000")}

我需要查找具有相同clientId值的所有文档,并使用具有“admin”角色的文档的值of_id更新clientId

例如:

   { "_id" : ObjectId("59593ba80000000000000000"), "role" : "admin", "clientId" : ObjectId("598b6c180000000000000000")},
{ "_id" : ObjectId("59821a280000000000000000"),"role" : "user", "clientId" : ObjectId("598b6c180000000000000000")},
{ "_id" : ObjectId("598228380000000000000000"),"role" : "user", "clientId" : ObjectId("598b6c180000000000000000")}

这3个具有相同的clientId,我想用这些3中角色为“admin”的文档的_id更新clientId。

然后在更新后,结果将是:

{ "_id" : ObjectId("59593ba80000000000000000"), "role" : "admin", "clientId" : ObjectId("59593ba80000000000000000")},
{ "_id" : ObjectId("59821a280000000000000000"),"role" : "user", "clientId" : ObjectId("59593ba80000000000000000")},
{ "_id" : ObjectId("598228380000000000000000"),"role" : "user", "clientId" : ObjectId("59593ba80000000000000000")}

3 个答案:

答案 0 :(得分:2)

您需要运行一个具有管道的聚合操作,该管道首先按clientId对文档进行分组,在组内创建一个最多包含2个元素的数组,即根文档' s {{1如果它的角色是_id并且是一个常量值,那么如果不是这样的话,则为0。

下一个管道将过滤前一个管道中的文档,并返回上述组中具有多个计数的文档。

然后,前面的管道步骤将展平此数组以返回文档中的非规范化字段,然后过滤非规范化字段,使其只具有具有角色" admin"的文档。 "admin"。在执行此管道时,使用光标迭代结果并更新您的集合。

以下示例演示了以上内容:

_id

对于非常大的集合,您可以使用 initializeUnorderedBulkOp() 来批量更新您的集合,因为这可以显着加快性能,因为写入都在服务器上完成一次而没有往返

var cursor = db.collection.aggregate([
    {
        "$group": {
            "_id": "$clientId",
            "docId": {
                "$addToSet": {
                    "$cond": [
                        { "$eq": ["$role", "admin"] },
                        "$_id",
                        0
                    ]
                }
            },
            "count": { "$sum": 1 }
        }
    },
    { "$match": { "count": { "$gt": 1 } } },
    { "$unwind": "$docId" },
    { "$match": { "docId": { "$ne": 0 } } }
])

cursor.forEach(function(doc){
    db.collection.update(
        { "clientId": doc._id },
        { "$set": { "clientId": doc.docId } }
    );      
})

答案 1 :(得分:0)

你走了!试试这个!

db.dbName.find({clientId:"bbbbb", role:"admin"}).forEach(function(doc){   
    doc.clientId = doc._id;
    db.dbName.save(doc); 
})

答案 2 :(得分:0)

尝试这个。

db.sameValue.find({“clientId”:ObjectId(“598b6c180000000000000000”),“role”:“admin”})。forEach(function(obj){obj.clientId = obj._id; db.sameValue。保存(OBJ);});