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

Mongoose bulkWrite upsert仅能创建文档无法更新的问题排查

问题

尝试用Mongoose 5.4实现批量upsert操作,参考相关方案后编写代码如下:

const update = await Company.bulkWrite([
    {
      'updateOne': {
        'filter': { 'url': result.url },
        'update': {
          testVal: 'testinggg'
        },
        'upsert': true,
      }
    },
  ]);

执行后得到响应:

{
  "ok": 1,
  "writeErrors": [],
  "writeConcernErrors": [],
  "insertedIds": [],
  "nInserted": 0,
  "nUpserted": 0,
  "nMatched": 1,
  "nModified": 1,
  "nRemoved": 0,
  "upserted": []
}

但实际文档并未更新。修改filter创建新文档时正常,但匹配到现有文档时无法完成更新,尝试使用$set也无效:

const update = await Company.bulkWrite([
    {
      'updateOne': {
        'filter': { 'url': result.url },
        'update': {
          '$set': {
              testVal: 'testinggg'
          }
        },
        'upsert': true,
      }
    },
  ]);
分析与解决方案

出现该问题通常有以下几种原因及对应解决办法:

  • 版本兼容性bug
    Mongoose 5.4属于较旧版本,存在批量操作相关的已知bug。建议升级到5.x系列的稳定子版本(如5.13.x),或直接更新至更高版本,新版本已修复此类批量更新异常问题。

  • Schema定义限制
    检查Company模型的Schema配置:

    1. 确认testVal字段已在Schema中定义,且未设置immutable: true这类禁止修改的属性;
    2. 若testVal是新增字段,Schema默认的strict: true会阻止未定义字段被写入,可在update操作中添加strict: false选项,或修改Schema添加该字段:
      const update = await Company.bulkWrite([
          {
            'updateOne': {
              'filter': { 'url': result.url },
              'update': { '$set': { testVal: 'testinggg' } },
              'upsert': true,
              'options': { strict: false }
            }
          },
        ]);
      
  • Filter匹配的隐形差异
    尽管响应显示nMatched: 1,但result.url可能与文档中url存在隐形差异(如大小写、前后空格、编码不一致)。直接在MongoDB客户端执行db.companies.find({url: "你的result.url实际值"}),确认匹配到的文档是否为目标文档,且字段值无异常。

  • 未提交的事务或索引同步问题
    若代码中存在未完成的事务,会导致更新未持久化;如果url是索引字段,可尝试在操作后执行await Company.syncIndexes()确保索引同步,避免匹配异常。

内容的提问来源于stack exchange,提问作者snn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:47:22