且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Mongo在单个查询中批量查找和更新匹配的文档字段?

更新时间:2022-11-12 20:28:26

为提高性能,请充分利用

For improved performance, take advantage of using a Bulk() API for updating the collection efficiently in bulk as you will be sending the operations to the server in batches (for example, say a batch size of 500). This gives you much better performance since you won't be sending every request to the server but just once in every 500 requests, thus making your updates more efficient and quicker.

以下内容演示了这种方法,第一个示例使用 Bulk() API在MongoDB版本== 2.6和<中提供. 3.2.它通过将1递增到显示的字段来更新给定数组中集合中所有匹配的文档.假设图像阵列具有结构

The following demonstrates this approach, the first example uses the Bulk() API available in MongoDB versions >= 2.6 and < 3.2. It updates all the matched documents in the collection from a given array by incrementing 1 to the shown field. It assumes the array of images has the structure

var images = [
    { "_id": 1, "name": "img_1.png" },
    { "_id": 2, "name": "img_2.png" }
    { "_id": 3, "name": "img_3.png" },
    ...
    { "_id": n, "name": "img_n.png" }
]

MongoDB版本> = 2.6和< 3.2 :

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

images.forEach(function (doc) {    
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$inc": { "shown": 1 }
    });

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

下一个示例适用于新的MongoDB版本3.2,此版本自 Bulk() API,并使用

The next example applies to the new MongoDB version 3.2 which has since deprecated the Bulk() API and provided a newer set of apis using bulkWrite().

MongoDB 3.2及更高版本:

var ops = [];
images.forEach(function(doc) {
    ops.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$inc": { "shown": 1 }
            }
        }
    });

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

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