You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:52:50