Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

MongoDB 单次查询更新多行:使用 initializeUnorderedBulkOp()

本文演示如何使用 initializeUnorderedBulkOp() 在单次操作中批量更新多个文档(不同条件、不同更新内容),提高写入性能。

创建示例数据

> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"John","CustomerPurchaseAmount":500});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6ceb06d78f205348bc626") }
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"Chris","CustomerPurchaseAmount":700});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6ceb26d78f205348bc627") }
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"David","CustomerPurchaseAmount":50});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6ceb36d78f205348bc628") }
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"Larry","CustomerPurchaseAmount":1900});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6ceb46d78f205348bc629") }

显示所有数据

> db.upDateMultipleRowsDemo.find().pretty();
{ "_id" : ObjectId("5cd6ceb06d78f205348bc626"), "CustomerName" : "John", "CustomerPurchaseAmount" : 500 }
{ "_id" : ObjectId("5cd6ceb26d78f205348bc627"), "CustomerName" : "Chris", "CustomerPurchaseAmount" : 700 }
{ "_id" : ObjectId("5cd6ceb36d78f205348bc628"), "CustomerName" : "David", "CustomerPurchaseAmount" : 50 }
{ "_id" : ObjectId("5cd6ceb46d78f205348bc629"), "CustomerName" : "Larry", "CustomerPurchaseAmount" : 1900 }

批量更新:John 改名为 Bob,David 金额改为 56544444

> var manyUpdateValue = db.upDateMultipleRowsDemo.initializeUnorderedBulkOp();
> manyUpdateValue.find({ _id: ObjectId("5cd6ceb06d78f205348bc626") }).updateOne({$set:{"CustomerName":"Bob" }});
> manyUpdateValue.find({ _id: ObjectId("5cd6ceb36d78f205348bc628") }).updateOne({$set:{"CustomerPurchaseAmount":56544444}});
> manyUpdateValue.execute();
BulkWriteResult({
  "writeErrors" : [ ],
  "writeConcernErrors" : [ ],
  "nInserted" : 0,
  "nUpserted" : 0,
  "nMatched" : 2,
  "nModified" : 2,
  "nRemoved" : 0,
  "upserted" : [ ]
})

验证更新结果

> db.upDateMultipleRowsDemo.find().pretty();
{ "_id" : ObjectId("5cd6ceb06d78f205348bc626"), "CustomerName" : "Bob", "CustomerPurchaseAmount" : 500 }
{ "_id" : ObjectId("5cd6ceb26d78f205348bc627"), "CustomerName" : "Chris", "CustomerPurchaseAmount" : 700 }
{ "_id" : ObjectId("5cd6ceb36d78f205348bc628"), "CustomerName" : "David", "CustomerPurchaseAmount" : 56544444 }
{ "_id" : ObjectId("5cd6ceb46d78f205348bc629"), "CustomerName" : "Larry", "CustomerPurchaseAmount" : 1900 }

Bulk Operations 核心概念

方法说明
initializeUnorderedBulkOp()创建无序批量操作构建器(并行执行,性能更好)
initializeOrderedBulkOp()创建有序批量操作构建器(按顺序执行,遇错停止)
find(query)指定匹配条件
updateOne(update)更新第一个匹配文档
update(update)更新所有匹配文档 (multi)
replaceOne(replacement)替换第一个匹配文档
deleteOne()/delete()删除操作
execute()提交执行所有排队操作

现代替代方案 (MongoDB 3.2+): bulkWrite()

db.upDateMultipleRowsDemo.bulkWrite([
  { updateOne: {
    filter: { _id: ObjectId("5cd6ceb06d78f205348bc626") },
    update: { $set: { "CustomerName": "Bob" } }
  }},
  { updateOne: {
    filter: { _id: ObjectId("5cd6ceb36d78f205348bc628") },
    update: { $set: { "CustomerPurchaseAmount": 56544444 } }
  }}
]);

bulkWrite() 是推荐的新 API,支持 ordered/unordered 选项,返回标准化结果对象。

性能优势

  • 减少网络往返 (Round Trips)
  • 服务端批量处理,减少锁竞争
  • Unordered 模式可并行执行,吞吐量更高
  • 适合批量导入、ETL、定时任务更新