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
相关产品推荐
相关产品推荐

