MongoDB批量写入自动生成_id时出现E11000重复键错误求助
未手动指定_id却触发重复键错误的原因及修复方案
问题根源
你重复复用了同一个inserts数组中的文档对象。MongoDB驱动在执行第一次bulkWrite操作时,会自动为每个未指定_id的文档生成_id,并直接添加到原对象上。后续循环中,你再次将这些已经带有_id的对象推入bulkInserts,重复插入自然触发_id_唯一索引的冲突错误。
看你的代码逻辑:外层循环50次,每次内层循环都会把inserts的元素重复推入全局的bulkInserts数组,然后执行批量写入。第一次循环结束后,inserts里的所有文档都已经被驱动打上了_id标记,后续所有循环再复用这些对象时,_id完全重复,必然报错。
修复方案
核心思路是每次插入都生成全新的文档对象,避免复用已被添加_id的旧对象,同时调整bulkInserts的作用域避免操作累积:
- 将
inserts改为生成新数组的函数,每次调用返回全新的文档结构:
const getInserts = () => [ { insertOne: { document: { name: "a" } } }, { insertOne: { document: { name: "b" } } }, // 其他类似插入操作 ];
- 修改循环逻辑,每次外层循环重新初始化
bulkInserts,并调用函数获取新的插入对象:
const ops: Promise<any>[] = []; for (let i = 0; i < 50; i++) { const bulkInserts: any[] = []; // 移到外层循环内,每次清空 for (let x = 0; x < 50; x++) { bulkInserts.push(...getInserts()); // 每次获取新的文档对象 } ops.push(collection.bulkWrite(bulkInserts)); } await Promise.all(ops);
这样每次批量写入的都是全新的、未带_id的文档,驱动会为每个新文档生成唯一的_id,就不会再出现重复键错误了。
内容的提问来源于stack exchange,提问作者radop33392
相关产品推荐
相关产品推荐

