首页/数据/NoSQL 速查/bulkWrite 混合批量操作
MongoDB99 条

bulkWrite 混合批量操作

一次提交插入/更新/删除/替换的混合操作序列;ordered:true(默认)遇到失败停止后续,false 则继续并集中汇报错误。

NoSQL 速查数据更新于 2026-10-13

bulkWrite 是什么

bulkWrite 把一批混合操作(插入、更新、替换、删除)放在一个请求里提交,驱动按数组顺序发往服务端,省掉逐条往返的延迟。它有两种执行模式:ordered 为默认值 true,遇到第一个失败就停止后续操作;设为 false 则继续执行剩余操作,最后集中返回失败清单。批量导入、批量修复这类场景应优先考虑它。

基本信息

操作类型insertOne / updateOne / updateMany / replaceOne / deleteOne / deleteMany
执行模式ordered 默认 true;false 表示失败继续并集中汇报
返回内容insertedCount / matchedCount / modifiedCount / deletedCount / upsertedCount / upsertedIds
常用选项ordered、bypassDocumentValidation、writeConcern、session(事务内)
适用版本MongoDB 3.2 起支持;mongosh 与各语言驱动语法略有差异

典型使用场景

  • 数据初始化与迁移:一次提交数千条插入,显著减少往返开销
  • 订单批处理:同一批里既有状态更新也有过期记录删除,一条请求完成
  • 对账修复:按主键 upsert 一批记录,重复执行结果一致
  • 配合会话在副本集事务中批量写入,控制单次事务的操作规模
  • 压测与造数:快速写入大量混合操作验证索引与写入能力

语法与失败处理

语法与失败处理
// 混合操作:插入、递增更新、删除放在同一次提交里
db.orders.bulkWrite([
  { insertOne: { document: { _id: 2001, sku: "B-1", qty: 1 } } },
  { updateOne: { filter: { _id: 1001 }, update: { $inc: { qty: 1 } } } },
  { updateMany: { filter: { status: "expired" }, update: { $set: { archived: true } } } },
  { replaceOne: { filter: { _id: 1002 }, replacement: { sku: "C-9", qty: 5 }, upsert: true } },
  { deleteOne: { filter: { _id: 999 } } }
], { ordered: false, writeConcern: { w: "majority" } })  // 顺序无关时用 false 提升吞吐

// ordered:false 下必须逐项检查失败,冲突项会出现在 writeErrors 里
try {
  db.orders.bulkWrite(ops, { ordered: false })
} catch (e) {
  if (e.writeErrors) { printjson(e.writeErrors.map(function (w) { return { i: w.index, msg: w.errmsg } })) }
  else { throw e }
}

返回字段读法

字段含义排查用途
insertedCount成功插入的条数与预期条数不符说明有插入失败,需查 writeErrors
matchedCount按条件命中的文档数命中为 0 时检查过滤条件与字段类型是否匹配
modifiedCount实际发生修改的文档数小于 matchedCount 是常见现象,值相同则不计入修改
deletedCount删除的文档数与预期不符时先确认过滤条件
upsertedCount / upsertedIds新增文档数量与新文档主键未传 upsert:true 时不会出现该字段
writeErrors失败项数组,含 index 与 errmsgordered:false 下必须逐项读取,否则失败被静默吞掉
超大批次要自行分批:单次提交的操作条数与整个请求的 16MB BSON 体积都有上限(具体数字以所用驱动文档为准),且大事务会长时间持有锁与缓存压力,导入通常按每批几千条提交。
ordered:false 的批量写不是全有或全无:部分成功部分失败是常态,业务侧要能接受中间状态,并让失败项可重放且幂等。

易错点

  • ordered:false 下不检查 writeErrors:唯一键冲突被静默跳过,业务以为全部写入成功
  • 把整库导入塞进一个 bulkWrite:请求体积超过限制直接报错,拆批后重跑又要保证幂等
  • ordered:true 时把关键操作排在最后:前面一条失败导致关键写入根本没执行,顺序设计要按依赖排布
  • 在副本集上忘记传会话就期待原子性:bulkWrite 本身不提供跨文档事务语义,需要显式事务包裹

数据来源与参考

  • MongoDB Manual: db.collection.bulkWrite()
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌