node.js - 使用 mongoose 仅更新嵌套 json 文档中的一个元素
问题描述
当嵌套 json 元素时,如何使用 Mongoose 只更新文档中的一个部分?
我想更新一个文档,只需将“darkMode”从 false 设置为 true,而不需要 GETing 和 PUTing 整个“settins”部分。猫鼬可以做到这一点吗?
"settings": {
"darkMode": false,
"tipOfTheDay": true,
"paperFormat": "DINA4",
},
如果我放这个,我将丢失文档“设置”部分中的所有内容:
"settings": {
"darkMode": true,
},
我的 NodeJS 后端看起来像这样。我目前正在使用 findByIdAndUpdate 。也许有更好的方法?
exports.updateProfile = async (req, res, next) => {
const profile = await Profile.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true
});
if (!profile) {
return res.status(400).json({success: false});
}
res.status(200).json({success: true, data: profile});
}
解决方案
为了更新嵌入文档中的字段,您必须使用 a$set
运算符(因为您的文档是一个对象,我们正在处理对象中的一个对象)
从 mongodb 文档:
更新嵌入文档中的特定字段 使用点符号更新嵌入文档中的值。
所以对你来说,如果我们假设这里的 req.body{ darkMode: true }
是
const profile = await Profile.findByIdAndUpdate(
req.params.id,
{ $set: { 'settings.darkMode': req.body.darkMode } },
{
new: true,
runValidators: true
});
但这完全取决于您如何从客户端发送数据,如果您发送一个仅包含修改字段的对象,那么您必须专门 $set 它们以保持其他值不变,如上所示。要自动执行此操作,您还可以使用花哨的循环构建查询:
let query = { $set: {} }
Object.keys(req.body).forEach(requestBodyKey => {
let requestBodyFieldValue = req.body[requestBodyKey];
query.$set[`settings.${requestBodyKey}`] = requestBodyFieldValue;
})
或者您可以首先查询您的文档以获取 current_settings,然后使用 javascript 您将合并两个对象(例如,{...myCurrentSettings, ...myNewerSettings }
参见扩展运算符或Object.assign()),然后对其进行更新以确保您保留以前的、未触及的字段值。
推荐阅读
- r - R:如何使用另一列的值填充新列中的值
- python - 无法弄清楚代码有什么问题。尝试 string.find() 的替代方法
- javascript - 为什么我不能使用 instanceof 来确定一个元素是否是组件的实例?
- jekyll - noob 与 jekyll 语法高亮作斗争:呈现 HTML,但样式表似乎丢失
- c# - 搜索栏在MVC中找不到Controller中的动作
- sql - 从表 2 中选择一个值,该值依赖于表 1 中的另一个值 (Oracle SQL)
- sql - 连接、舍入和处理空值
- php - PHP MVC 管理面板我们应该如何创建呢?
- nginx - 如何修改 Nginx 提供的静态 HTML 文件?
- reactjs - 用于 TypeScript 的 Next.js with-redux 示例