Node.js中用Mongoose批量插入MongoDB文档:跳过错误并返回结果
解决Mongoose批量插入时跳过错误文档并返回结果的问题
核心解决方案是使用Mongoose的insertMany方法,并设置{ ordered: false }选项,这个配置会让MongoDB在遇到错误(比如重复键)时继续处理剩余文档,而不是直接终止整个操作。之后通过捕获BulkWriteError来区分成功和失败的文档,最终整理成包含每个文档插入状态的结果数组。
代码实现示例
首先定义你的Student模型:
const mongoose = require('mongoose'); const Student = mongoose.model('Student', new mongoose.Schema({ _id: Number, name: String }));
然后编写批量插入处理函数:
async function bulkInsertStudents(docs) { const result = { inserted: [], failed: [] }; try { // 插入所有文档,设置ordered: false跳过错误继续执行 const insertedDocs = await Student.insertMany(docs, { ordered: false }); result.inserted = insertedDocs.map(doc => ({ ...doc.toObject(), status: 'success' })); } catch (err) { // 处理批量写入错误 if (err.name === 'BulkWriteError') { // 提取成功插入的文档 result.inserted = err.result.insertedDocs.map(doc => ({ ...doc, status: 'success' })); // 提取失败的文档及对应错误信息 err.writeErrors.forEach(writeErr => { const failedDoc = docs[writeErr.index]; result.failed.push({ ...failedDoc, status: 'failed', error: writeErr.errmsg }); }); } else { // 处理其他类型错误(比如模型验证失败等) result.failed = docs.map(doc => ({ ...doc, status: 'failed', error: err.message })); } } // 按原文档顺序整理最终结果 const finalResult = docs.map(doc => { const matchedInsert = result.inserted.find(item => item._id === doc._id); if (matchedInsert) return matchedInsert; const matchedFailed = result.failed.find(item => item._id === doc._id); return matchedFailed || { ...doc, status: 'unknown' }; }); return finalResult; }
效果验证
用你提供的示例输入调用函数:
const testDocs = [ {_id: 11, name:'abc'}, {_id: 22, name:'abc'}, {_id: 11, name:'qwe'}, {_id: 33, name:'xyz'} ]; bulkInsertStudents(testDocs).then(res => console.log(res));
返回的结果会是:
[ { _id: 11, name: 'abc', status: 'success' }, { _id: 22, name: 'abc', status: 'success' }, { _id: 11, name: 'qwe', status: 'failed', error: 'E11000 duplicate key error collection: test.students index: _id_ dup key: { _id: 11 }' }, { _id: 33, name: 'xyz', status: 'success' } ]
关键说明
ordered: false:这是实现需求的核心配置,默认情况下insertMany是按顺序执行的,遇到第一个错误就会终止,设置这个选项后MongoDB会并行处理文档,跳过错误继续执行剩余插入。BulkWriteError:当批量插入部分失败时,Mongoose会抛出这个特定错误,其中包含了成功插入的文档列表和每个失败文档的错误详情(包括错误发生在原数组中的索引位置)。- 结果整理:通过原文档的
_id匹配成功/失败记录,确保最终结果的顺序和输入一致,符合你的预期。
内容的提问来源于stack exchange,提问作者Vishal Gupta
相关产品推荐
相关产品推荐

