Mongoose 多更新

2024-04-25

我想用不同的值更新多个文档。

我的数据库看起来像这样。

[
    {
        "_id": 1,
        "value": 50
    },
    {
        "_id": 2,
        "value": 100
    }
]

此查询返回错误,因为我传递的是数组而不是 $set 中的对象。

    Model.update({_id: {$in: ids}}, {$set: ids.value}, {multi: true};

我希望我的数据库看起来像这样

[
        {
            "_id": 1,
            "value": 4
        },
        {
            "_id": 2,
            "value": 27
        }
    ]

假设你有一个对象数组,你想在你的集合中更新匹配的 id,例如

var soldItems = [
        {
            "_id": 1,
            "value": 4
        },
        {
            "_id": 2,
            "value": 27
        }
    ];

那么你可以使用forEach() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach数组上的方法来迭代它并更新您的集合:

soldItems.forEach(function(item)){
    Model.update({"_id": item._id}, {"$set": {"value": item.value }}, callback);
});

或使用承诺作为

var updates = [];
soldItems.forEach(function(item)){
    var updatePromise = Model.update({"_id": item._id}, {"$set": {"value": item.value }});
    updates.push(updatePromise);
});

Promise.all(updates).then(function(results){
    console.log(results);
});

或使用map() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

var updates = soldItems.map(function(item)){
    return Model.update({"_id": item._id}, {"$set": {"value": item.value }});       
});

Promise.all(updates).then(function(results){
    console.log(results);
}); 

对于较大的数组,您可以利用批量写入 API 来获得更好的性能。对于猫鼬版本>=4.3.0哪个支持MongoDB Server 3.2.x, 您可以使用bulkWrite() https://docs.mongodb.org/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite用于更新。以下示例展示了如何执行此操作:

var bulkUpdateCallback = function(err, r){
    console.log(r.matchedCount);
    console.log(r.modifiedCount);
}
// Initialise the bulk operations array
var bulkOps = soldItems.map(function (item) { 
    return { 
        "updateOne": { 
            "filter": { "_id": item._id } ,              
            "update": { "$set": { "value": item.value } } 
        }         
    }    
});

// Get the underlying collection via the native node.js driver collection object
Model.collection.bulkWrite(bulkOps, { "ordered": true, w: 1 }, bulkUpdateCallback);

对于猫鼬版本~3.8.8, ~3.8.22, 4.x支持 MongoDB 服务器>=2.6.x,你可以使用Bulk API https://docs.mongodb.org/manual/reference/method/Bulk/如下

var bulk = Model.collection.initializeOrderedBulkOp(),
    counter = 0;

soldItems.forEach(function(item) {
    bulk.find({ "_id": item._id }).updateOne({ 
        "$set": { "value": item.value }
    });

    counter++;
    if (counter % 500 == 0) {
        bulk.execute(function(err, r) {
           // do something with the result
           bulk = Model.collection.initializeOrderedBulkOp();
           counter = 0;
        });
    }
});

// Catch any docs in the queue under or over the 500's
if (counter > 0) {
    bulk.execute(function(err,result) {
       // do something with the result here
    });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mongoose 多更新 的相关文章