2015-04-23 63 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(); 
相关问题