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"
];
Run Code Online (Sandbox Code Playgroud)
那么对于非常小的数据集,您可以使用updateMany()数组上的方法迭代它并更新您的集合:
Model.updateMany(
{ "_id": { "$in": processedIds } },
{ "$set": { "status": "processed" } },
callback
);
Run Code Online (Sandbox Code Playgroud)
以上对于小型数据集是可以的.但是,当您面对要更新的数千或数百万个文档时,这将成为一个问题,因为您将在循环内重复调用异步代码的服务器.
另一种方法是使用像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);
});
Run Code Online (Sandbox Code Playgroud)
对于猫鼬的版本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); }
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以{multi: true}在更新查询中使用选项进行批量更新。
范例:
employees.update({ _id: { $gt: 3 } },{$inc: { sortOrder: -1 }},{'multi':true});
Run Code Online (Sandbox Code Playgroud)
上面的代码在mongoose中等效于下面的代码在mongodb中:
db.employees.updateMany({ _id: { $gt: 3 } },{$inc: { sortOrder: -1 }});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16629 次 |
| 最近记录: |