当json元素嵌套时,如何用Mongoose更新文档中的一个?
我想更新一个文档,只是将“ darkMode”从false设置为true,而无需获取和放置整个“ 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});
}
答案 0 :(得分:1)
要更新嵌入文档中的字段,您必须使用$set
运算符(由于您的文档是对象,因此我们正在处理对象中的对象)
从mongodb文档中:
更新嵌入式文档中的特定字段 使用点符号来更新嵌入式文档中的值。
因此,对于您来说,如果我们假设此处的要求正文为{ 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 }
see spread operator或Object.assign()),然后对其进行更新以确保您将保留之前未更改的字段值。