MongoDB:使用某些标准更新多个文档

时间:2016-11-29 15:26:23

标签: json mongodb

以下是我的数据库中的集合中的样子:

{
    row_num: 1,
    value: 15
}
{
    row_num: 2,
    value: 74
}
...

现在我有以下更新的JSON文件:

{
    row_num: 1,
    value: 16
}
{
    row_num: 2,
    value: 28
}
...

将一对一映射到MongoDB中的数据。我的问题是,是否可以使用MongoDB语法在一行中更新每个文档中的值,而不是在我的脚本中有一个循环来更新它?

1 个答案:

答案 0 :(得分:1)

当您使用 Bulk() API进行更新时,可以使用循环向JSON数组中的每个文档发送更新请求。这也是 已经提高了性能,因为您将批量发送操作到服务器(例如,批量大小为500),使您的更新更有效,更快捷。

以下演示了此方法,第一个示例使用MongoDB版本中的 Bulk() API> = 2.6和< 3.2。它通过将现有的value字段修改为JSON中的字段来更新给定数组中集合中的所有匹配文档:

var updatedJsonArray = [
    { "row_num": 1, "value": 16 },
    { "row_num": 2, "value": 28 },
    { "row_num": 3, "value": 43 },
    ...
    { "row_num": 15478, "value": 9 }
]

MongoDB版本> = 2.6和< 3.2

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

updatedJsonArray.forEach(function (doc) {    
    bulk.find({ "row_num": doc.row_num }).updateOne({ 
        "$set": { "value": doc.value }
    });

    counter++;
    if (counter % 500 === 0) {
        // Execute per 500 operations
        bulk.execute(); 
        // re-initialize every 500 update statements
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})
// Clean up remaining queue
if (counter % 500 !== 0) { bulk.execute(); }

下一个示例适用于自deprecated Bulk() API以来的新MongoDB版本3.2,并使用 {{3}提供了一套更新的api }

MongoDB 3.2及更高版本

var ops = [];
updatedJsonArray.forEach(function(doc) {
    ops.push({
        "updateOne": {
            "filter": { "row_num": doc.row_num },
            "update": {
                "$set": { "value": doc.value }
            }
        }
    });

    if (ops.length === 500) {
        db.collection.bulkWrite(ops);
        ops = [];
    }
})

if (ops.length > 0)  
    db.collection.bulkWrite(ops);