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

Mongoose批量操作执行$push更新报错如何解决

报错原因

这个错误由更新操作写法错误直接触发:

  • 你将$push更新操作符嵌套在了$set的参数对象中,MongoDB会把$set接收的对象识别为「待赋值的普通字段集合」,这类场景下不允许出现$开头的字段名,因此抛出异常。
  • 原代码还存在2个隐藏问题:
    • docUpdates数组中存储主键的字段名是id,循环拼接查询条件时读取的是docUpdates[i].docId,字段名不匹配会导致查询条件为空,更新错配数据
    • 第二条更新记录的status值存在拼写错误:compelted的正确拼写为completed
修复方案

方案1:修正原生有序批量操作写法

将普通字段赋值、数组追加操作拆为同级的更新操作符,禁止把$push这类操作符嵌套在$set内部,修正后可直接运行的代码如下:

const docUpdates = [
    {
        _id: docId1, // 统一用_id存储主键,和查询条件字段对齐
        status: "created",
        pushRecord: {
            status: "created",
            referenceId: referenceId,
            createdTimestamp: "2022-06-14T00:00:00.000Z"
        }
    },
    {
        _id: docId2,
        status: "completed",
        pushRecord: {
            status: "completed", // 修正拼写错误
            referenceId: referenceId,
            createdTimestamp: "2022-06-14T00:00:00.000Z"
        }
    },
];

// 初始化有序批量操作实例
const bulkUpdate = Model.collection.initializeOrderedBulkOp();

for (const item of docUpdates) {
    bulkUpdate.find({ _id: item._id }).updateOne({
        $set: { status: item.status }, // $set仅承载普通字段的赋值逻辑
        $push: { updates: item.pushRecord } // $push和$set为同级更新操作符,独立声明
    })
}

// 执行批量操作,必须加await等待结果,否则会出现未捕获的Promise异常
const res = await bulkUpdate.execute();

方案2:使用Mongoose封装的bulkWrite API(推荐)

不需要手动初始化批量操作实例,Mongoose会自动处理底层逻辑,写法更简洁,出错概率更低:

// 构造批量操作数组
const bulkOps = docUpdates.map(item => ({
    updateOne: {
        filter: { _id: item._id },
        update: {
            $set: { status: item.status },
            $push: { updates: item.pushRecord }
        }
    }
}));

// 执行批量操作,ordered: true对应原有序批量操作的语义
const res = await Model.bulkWrite(bulkOps, { ordered: true });
核心注意点

MongoDB所有更新操作符($set/$push/$inc/$pull等)都必须放在update参数的顶层同级位置,禁止将一个更新操作符嵌套在另一个更新操作符的参数对象中,否则都会触发同类的字段不允许错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:00:51