如何使用Mongoose、Node.js及Axios更新嵌套对象且不丢失原有属性
问题原因
你现有代码存在两个问题:
- 调用
updateMany时多套了一层括号,Templates.updateMany((req.query, req.body))里的括号触发了逗号运算符,最终等于只传了req.body作为查询条件,没有正确传入更新参数,还导致req.query里的_ref字段被误写入文档顶级字段。 - 直接传入
{ remindTime: { date: '2021-09-28' } }作为更新内容时,MongoDB会直接把整个remindTime嵌套对象替换为你传入的新对象,原有time属性会被覆盖清除。
修复方案
只需要指定更新嵌套字段的完整路径即可,不需要替换整个remindTime对象,提供两种可选实现:
方案1:仅修改后端代码(无需调整前端请求)
// 构造符合点语法规则的更新对象 const updateData = {} // 提取remindTime下的字段单独赋值,保留原有其他嵌套属性 if (req.body.remindTime) { Object.entries(req.body.remindTime).forEach(([key, value]) => { updateData[`remindTime.${key}`] = value }) // 清除原remindTime顶级属性避免覆盖 delete req.body.remindTime } // 合并其他需要更新的顶级字段 Object.assign(updateData, req.body) Templates.updateMany(req.query, { $set: updateData }) .then( (record) => res.status(200).json(record), (err) => res.status(400).json(err) )
方案2:调整前端请求体格式
前端Axios请求的body直接传嵌套字段的完整路径:
{ "remindTime.date": "2021-09-28" }
后端仅需修正括号和加上$set操作符即可:
Templates.updateMany(req.query, { $set: req.body }) .then( (record) => res.status(200).json(record), (err) => res.status(400).json(err) )
内容的提问来源于stack exchange,提问作者Jerry Seigle
相关产品推荐
相关产品推荐

