2017-03-02 61 views
2

如何更新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")} 

我需要找到所有與同一個客戶端價值的文件,並更新其爲具有角色「管理員」

例如,文件的價值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個具有同一個客戶端,我想更新其角色的文檔_id ClientID的是其中3

0123「管理員」

然後更新後,結果將是:

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

嘗試使用moongose http://mongoosejs.com/docs/guide.html –

+0

我需要在shell中運行查詢 – Sabreena

+0

什麼是您的MongoDB服務器版本? – chridam

回答

2

您將需要運行具有流水線其中第一組由clientId的文件,該組中創建最多2個元素的數組,即根文檔的_id如果它的作用是"admin"聚集操作一個常數值,如果沒有其他值,則爲0。

下一個管道將過濾從以前的管道的文件,並返回那些對上述組多於一項罪名。

上一個管道步驟將平鋪該數組以返回文檔中的非規格化字段,然後過濾非規格化字段以僅使文檔具有角色「admin」_id。在執行此管道時,使用光標來迭代結果並更新您的集合。

下面的示例演示上面:

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 } } 
    );  
}) 

對於非常大的集合,你可以使用initializeUnorderedBulkOp()散裝更新您的收藏爲的寫入是這一切可以顯著加速性能在服務器上完成一次而沒有往返行程

var bulk = db.collection.initializeUnorderedBulkOp(), 
    counter = 0; 

cursor.forEach(function(doc){ 
    bulk.find({ "clientId": doc._id }).update({ "$set": { "clientId": doc.docId } }); 

    counter++; // increment counter for batch limit 
    if (counter % 500 === 0) { 
     // execute the bulk update operation in batches of 500 
     bulk.execute(); 
     // Re-initialize the bulk update operations object 
     bulk = db.collection.initializeUnorderedBulkOp(); 
    } 
}) 

// Clean up remaining operation in the queue 
if (counter % 500 !== 0) { bulk.execute(); } 
+1

您的樣品謝謝@chridam – Sabreena

+0

@Sabreena不用擔心,樂於幫助:) – chridam

0

在這裏你去!嘗試這個!

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

試試這個。 ({「clientId」:ObjectId(「598b6c180000000000000000」),「role」:「admin」})。forEach(function(obj){obj.clientId = obj._id; db.sameValue .save(OBJ);});

相關問題