本文演示如何使用 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、定时任务更新