鉴于这三个文件:
db.test.save({"_id":1, "foo":"bar1", "xKey": "xVal1"});
db.test.save({"_id":2, "foo":"bar2", "xKey": "xVal2"});
db.test.save({"_id":3, "foo":"bar3", "xKey": "xVal3"});
Run Code Online (Sandbox Code Playgroud)
以及引用这些文档的单独信息数组:
[{"_id":1, "foo":"bar1Upd"},{"_id":2, "foo":"bar2Upd"}]
Run Code Online (Sandbox Code Playgroud)
是否可以在一次操作中更新两个引用文档(1 和 2)上的“foo”?
我知道我可以遍历数组并一个一个地执行它们,但是我有数千个文档,这意味着到服务器的往返次数太多。
非常感谢您的想法。
不可能在单个原子操作中更新两个引用文档(1 和 2)上的“foo”,因为 MongoDB 没有这种机制。但是,看到您有一个大集合,一种选择是利用Bulk API允许您批量发送更新而不是每个更新请求到服务器。
该过程涉及循环数组中的所有匹配文档并处理批量更新,这至少允许在具有单一响应的单个请求中发送许多操作。
这为您提供了更好的性能,因为您不会将每个请求发送到服务器,而是每 500 个请求发送一次,从而使您的更新更高效、更快捷。
-编辑-
选择较低值的原因通常是受控选择。正如那里的文档中所述,默认情况下,MongoDB 将最多一次以 1000 个操作的批次发送到服务器,并且不能保证确保这些默认的 1000 个操作请求实际上符合16MB BSON 限制。因此,您仍然需要站在“安全”的一边,并强加您只能有效管理的较低批量大小,以便在发送到服务器时它的总数小于数据大小限制。
让我们用一个例子来演示上面的方法:
a)如果使用 MongoDB v3.0 或更低版本:
var bulk = db.test.initializeOrderedBulkOp(),
largeArray = [{"_id":1, "foo":"bar1Upd"},{"_id":2, "foo":"bar2Upd"}],
counter = 0;
largeArray.forEach(doc) {
bulk.find({ "_id": doc._id }).updateOne({ "$set": { "foo": doc.foo } });
counter++;
if (counter % 500 == 0) {
bulk.execute();
bulk = db.test.initializeOrderedBulkOp();
}
}
if (counter % 500 != 0 ) bulk.execute();
Run Code Online (Sandbox Code Playgroud)
b)如果使用 MongoDB v3.2.X 或更高版本(新的 MongoDB 3.2 版已弃用该Bulk()API 并使用 提供了一组较新的 api bulkWrite()):
var largeArray = [{"_id":1, "foo":"bar1Upd"},{"_id":2, "foo":"bar2Upd"}],
bulkUpdateOps = [];
largeArray.forEach(function(doc){
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "foo": doc.foo } }
}
});
if (bulkUpdateOps.length === 500) {
db.test.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (bulkUpdateOps.length > 0) db.test.bulkWrite(bulkUpdateOps);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3039 次 |
| 最近记录: |