首页 / MongoDB 入门教程 / 批量插入与写关注

MongoDB 入门教程

批量插入与写关注

本教程共 50 篇 · 第 12 篇 · 更新于 2026-07-30 · 约 8 分钟阅读

MongoDBMongoDB 入门教程insertManyorderedunorderedWrite Concern写关注

12. 批量插入与写关注

本节目标:理解批量插入里 ordered 和 unordered 的区别,搞懂写关注(Write Concern)怎么控制「写多稳才算成功」。

12.1 有序 vs 无序

insertMany 第二个参数可以传选项,其中 ordered 决定出错时怎么处理:

  • ordered: true(默认):按顺序插入,遇到一条失败就停下,后面的不再写。
  • ordered: false:无序插入,某条失败也继续写剩下的。
// 有序:默认行为,遇到错误就中断
db.users.insertMany([
  { _id: 2, name: "李娜" },
  { _id: 2, name: "重复会报错" },  // 这一条 _id 重复
  { _id: 3, name: "王芳" }          // 前面报错,这条不会执行
])
// 无序:即使中间失败,其余照常写入
db.users.insertMany([
  { _id: 2, name: "李娜" },
  { _id: 2, name: "重复会报错" },
  { _id: 3, name: "王芳" }
], { ordered: false })
Tip

如果你只是批量灌测试数据、不关心顺序,用 ordered: false 能让一条坏数据不拖累整批。生产写入要顺序保证时,留默认 true

12.2 批量错误的返回

出错时返回里会带失败的详情,而不是整个操作「消失」:

MongoBulkWriteError: E11000 duplicate key error ...
result: {
  acknowledged: true,
  insertedCount: 1,
  insertedIds: { '0': 2 }
}

注意:即便报错了,acknowledged 仍是 true,表示那些成功的确实写进去了。

12.3 什么是写关注

写关注(Write Concern)回答一个问题:「要多少节点确认收到,这次写入才算成功?」

常用取值:

取值含义
w: 1主节点(primary)确认即可,最快但可能回滚
w: "majority"多数节点确认,更耐用,延迟略高
w: 0不等待确认(不推荐,出错你不知道)
// 插入时指定写关注:等多数节点确认,5 秒超时
db.orders.insertOne(
  { _id: 1001, total: 377, status: "paid" },
  { writeConcern: { w: "majority", wtimeout: 5000 } }
)

12.4 默认写关注是什么

这点容易搞错,分两种情况:

Note

据 MongoDB 8.3 官方文档,自 5.0 起,副本集(Replica Set)的隐式默认写关注是 w: "majority";而单机(standalone)部署因为没有其他节点,默认等效于 w: 1

换句话说:

  • 你本机单机 mongod 学习,默认就是主节点确认。
  • 上到副本集生产环境,默认就要等多数节点确认才返回,数据更不容易丢。

12.5 超时 wtimeout

wtimeout 防止写关注永远等下去。超过这个时间还没达到要求,就报写关注错误,但已写的节点上数据可能还在。

// 多数节点 3 秒内没确认就报错返回
{ writeConcern: { w: "majority", wtimeout: 3000 } }
Warning

wtimeout 触发只代表「没能按时确认」,不代表数据没写进去。客户端要按「可能已写入」来兜底处理,而不是简单当失败。

12.6 选哪个写关注

  • 日志、埋点这类丢了不心疼:默认(w:1)够快。
  • 订单、账务这类绝不能丢:用 w: "majority"
  • 对延迟极度敏感又想保一点安全:折中用 w: 2(如果有 3 个以上节点)。
Tip

学习阶段不用显式写 writeConcern,用默认即可。真上线时,按业务重要性逐类设置,而不是全库一刀切。