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

mongoose使用findByIdAndUpdate更新comments数组时旧值被覆盖怎么办

问题解决

你遇到的comments数组被覆盖的问题由两处错误直接导致:

  • findByIdAndUpdate 参数顺序错误:该方法的参数规则为 (查询条件, 更新操作配置, 全局配置项),你将$set操作写在了第三个参数(全局配置)的位置,完全不会生效;同时你直接把req.body作为第二个参数传入,只要请求体中携带comments字段,Mongoose会直接用传入的值替换整个数组,自然会覆盖旧数据。
  • 操作符使用错误:$set的作用是直接替换目标字段的值,本来就不具备数组追加能力,要追加数组元素需要使用$push(允许重复元素)或$addToSet(自动去重)操作符。

另外注意你贴出的Schema是Ticket模型的,但控制器中操作的是User模型,需要确认User模型中也正确定义了Array类型的comments字段。

修正后的代码示例

假设你每次提交的是单条新评论,修改逻辑如下:

const updateUser = async (req, res) => {
    const {
        body: {username, email, firstname, lastname, country, password, newComment},
        params: { id: employeeId }
    } = req;

    // 构造更新操作,区分普通字段更新和数组追加
    const updateConfig = {
        // 普通字段用$set更新
        $set: {
            username,
            email,
            firstname,
            lastname,
            country
            // 密码建议单独做修改逻辑,不要和普通更新放在一起避免误改
        },
        // 数组追加用$push
        $push: {
            comments: newComment
        }
    }

    const user = await User.findByIdAndUpdate(employeeId, updateConfig, {
        new: true,
        runValidators: true
        // 非必要不要开upsert,避免找不到用户时生成冗余数据
    }).select(["-password"]);

    // 原有业务逻辑不变
    if (user?.type?.startsWith("IT") || user?.type?.startsWith("ADM")) {
        throw new NotFoundError(`No user with id ${employeeId}`);
    }
    if (!user) {
        throw new NotFoundError(`No user with id ${employeeId}`);
    }

    res.status(StatusCodes.OK).json({user});
};

如果需要一次性追加多条评论,可以使用$each修饰符:

$push: {
    comments: {
        $each: [评论1, 评论2, 评论3]
    }
}

如果需要自动过滤重复的评论,把$push替换为$addToSet即可,用法完全一致。

额外注意

不要直接把整个req.body传入更新配置,会导致恶意用户传入未授权字段(比如用户类型、权限等级)被直接更新,建议显式指定所有允许更新的字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:15:05