Ond*_*kar 17 mongoose mongodb node.js
我使用Mongoose从MongoDB中提取一些记录,将它们导入另一个系统,然后我想将所有这些文档的状态(文档属性)设置为processed.
我可以找到这个解决方案:通过id set更新多个文档.猫鼬
我想知道这是否是正确的方法,建立一个由所有文档ID组成的标准,然后执行更新.还请考虑一个事实,即它将是许多文件.
(更新查询的限制是什么?无法在任何地方找到它.官方文档:http://mongoosejs.com/docs/2.7.x/docs/updating-documents.html)
chr*_*dam 22
构建由所有文档ID组成的标准然后执行更新的方法必然会引起潜在的问题.当您迭代发送每个文档的更新操作的文档列表时,在Mongoose中,您冒着炸毁服务器的风险,特别是在处理大型数据集时,因为您没有等待异步调用完成,然后再转到下一个迭代.您将基本上构建一个未解决的操作的"堆栈",直到这导致问题 - Stackoverflow.
例如,假设您有一组文档ID,您希望在状态字段上更新匹配的文档:
var processedIds = [
    "57a0a96bd1c6ef24376477cd",
    "57a052242acf5a06d4996537",
    "57a052242acf5a06d4996538"
];
那么对于非常小的数据集,您可以使用updateMany()数组上的方法迭代它并更新您的集合:
Model.updateMany(
    { "_id": { "$in": processedIds } }, 
    { "$set": { "status": "processed" } }, 
    callback
);
以上对于小型数据集是可以的.但是,当您面对要更新的数千或数百万个文档时,这将成为一个问题,因为您将在循环内重复调用异步代码的服务器.
另一种方法是使用像async这样的东西forEach()并迭代数组,为每个项目执行MongoDB更新操作,同时从不执行多于x个并行更新.
最好的方法是使用批量API,这对于批量处理更新非常有效.性能与在多个文档中的每个文档上调用更新操作的差异在于,不是每次迭代都向服务器发送更新请求,而是批量API在每1000个请求(批处理)中发送一次请求.
对于eachLimit支持MongoDB Server的Mongoose版本>=4.3.0,您可以使用3.2.x更新.以下示例显示了如何进行此操作:
processedIds.forEach(function(id)){
    Model.update({"_id": id}, {"$set": {"status": "processed" }}, callback);
});
对于猫鼬的版本bulkWrite(),~3.8.8,~3.8.22支持MongoDB的服务器4.x,你可以按如下方式使用批量API
var bulkUpdateCallback = function(err, r){
    console.log(r.matchedCount);
    console.log(r.modifiedCount);
}
// Initialise the bulk operations array
var bulkUpdateOps = [],
    counter = 0;
processedIds.forEach(function(id) {
    bulkUpdateOps.push({
        "updateOne": {
            "filter": { "_id": id },
            "update": { "$set": { "status": "processed" } }
        }
    });
    counter++;
    if (counter % 500 == 0) {
        // Get the underlying collection via the native node.js driver collection object
        Model.collection.bulkWrite(bulkOps, { "ordered": true, w: 1 }, bulkUpdateCallback);
        bulkUpdateOps = []; // re-initialize
    }
})
if (counter % 500 != 0) { Model.collection.bulkWrite(bulkOps, { "ordered": true, w: 1 }, bulkUpdateCallback); }
小智 6
您可以{multi: true}在更新查询中使用选项进行批量更新。
范例:
employees.update({ _id: { $gt: 3 } },{$inc: { sortOrder: -1 }},{'multi':true});
上面的代码在mongoose中等效于下面的代码在mongodb中:
db.employees.updateMany({ _id: { $gt: 3 } },{$inc: { sortOrder: -1 }});
| 归档时间: | 
 | 
| 查看次数: | 16629 次 | 
| 最近记录: |