从键值对列表更新一组文档

Updating a set of documents from a list of key value pairs

我正在寻找是否有更好的方法来执行这种特定类型的批量更新。

如果我有 _idvalues 的列表或地图,这样:

var updates = [
  {_id: "abc", field: 12},
  {_id: "abd", field: 32},
  {_id: "xyz", field: 22},
  // ... snip (100 or more records) ...
}

并且我想在列出的每个文档上使用 field 的新值更新 myCollection,例如:

var update;
for (var i = 0; i < updates.length; i++){
   update = updates[i];
   db.myCollection.update({_id: update._id}, {$set: {field: update.field}});
}

但这似乎过时了,因为它必须将每个查询一个一个地往返于服务器。

在 SQL 中,我会通过执行单个查询(或使用临时表)来避免额外的往返:

WITH batch_update (_id uuid, value int) as (
  VALUES (...)
);
UPDATE my_table
SET
   value = bu.value
FROM 
   batch_update as bu
WHERE
   bu._id = my_table._id;

所以。有没有更好的方法来实现这个结果?

您可以使用 Bulk API 来实现。

var updates = [{"_id": "abc", "field": 12},
              {"_id": "abd", "field": 32},
              {"_id": "xyz", "field": 22}];
var bulk = db.myCollection.initializeUnorderedBulkOp();
var update = undefined;
for (var i = 0; i < updates.length; i++){
    update = updates[i];
    bulk.find( {_id: update._id} ).update( {$set: {field: update.field}} );
}
bulk.execute();

此外,您可以添加逻辑以每 100 条左右的记录调用一次 bulk.execute()