2015-04-23 67 views
4

假設我有一個像MongoDB中的子文檔數組有沒有辦法在每個subcoument添加一個新的領域

{ 
    "_id" : 5, 
    "rows": [ 
     { "id" : "aab", "value":100}, 
     { "id" : "aac", "value":400}, 
     { "id" : "abc", "value":200}, 
     { "id" : "xyz", "value":300} 
    ] 
} 

的文件,我需要每個子文件「狀態」中添加一個新的關鍵:1和結果應該看起來像

{ 
    "_id" : 5, 
    "rows": [ 
     { "id" : "aab", "value":100, "status":1}, 
     { "id" : "aac", "value":400, "status":1}, 
     { "id" : "abc", "value":200, "status":1}, 
     { "id" : "xyz", "value":300, "status":1} 
    ] 
} 

我怎麼能通過單個更新查詢做到這一點?

回答

1

Mongo positional operator$elemMatch有問題;

$操作符可以更新與使用$ elemMatch()運算符指定的多個查詢條件相匹配的第一個數組元素。

因此,這種情況下使用mongo查詢,你應該只更新特定的匹配標準。如果你在比賽設置rows.aac,那麼你將在row.aac陣列添加status:1,如下檢查查詢:

db.collectionName.update({ 
    "_id": 5, 
    "rows": { 
    "$elemMatch": { 
     "id": "abc" 
    } 
    } 
}, { 
    $set: { 
    "rows.$.status": 1 
    } 
}, true, false) // here you insert new field so upsert true 

mongo update展示如何upsertmulti作品。

但是你仍然想要更新所有文件,那麼你應該使用一些programming code或一些script。下面的代碼更新使用的所有數據cursor forEach

db.collectionName.find().forEach(function(data) { 
    for (var ii = 0; ii < data.rows.length; ii++) { 
    db.collectionName.update({ 
     "_id": data._id, 
     "rows.id": data.rows[ii].id 
    }, { 
     "$set": { 
     "rows.$.status": 1 
     } 
    }, true, false); 
    } 
}) 

如果你的文件大小更然後更好的方式來使用mongo bulk update下面的代碼演示瞭如何使用蒙戈批量更新:

var bulk = db.collectionName.initializeOrderedBulkOp(); 
var counter = 0; 
db.collectionName.find().forEach(function(data) { 
    for (var ii = 0; ii < data.rows.length; ii++) { 

    var updatedDocument = { 
     "$set": {} 
    }; 

    var setStatus = "rows." + ii + ".status"; 
    updatedDocument["$set"][setStatus] = 101; 
    // queue the update 
    bulk.find({ 
     "_id": data._id 
    }).update(updatedDocument); 
    counter++; 
    // re-initialize every 1000 update statements 
    if (counter % 1000 == 0) { 
     bulk.execute(); 
     bulk = db.collectionName.initializeOrderedBulkOp(); 
    } 
    } 

}); 
// Add the rest in the queue 
if (counter % 1000 != 0) 
    bulk.execute(); 
相關問題