node.js - 使用 mongoose 更新嵌套 json 文档中的一个元素

标签 node.js mongodb mongoose

当 json 元素嵌套时,如何使用 Mongoose 更新文档中的一小部分?

我想更新文档,只需将“darkMode”从 false 设置为 true,而不对整个“settins”部分进行 GET 和 PUT 操作。 Mongoose 可以做到这一点吗?

        "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});
}

最佳答案

为了更新嵌入文档中的字段,您必须使用 $set 运算符(因为您的文档是一个对象,我们正在处理对象中的对象)

来自 mongodb 文档:

https://docs.mongodb.com/v2.4/reference/method/db.collection.update/#update-specific-fields-in-embedded-documents

Update Specific Fields in Embedded Documents Use dot notation to update values in embedded documents.

所以对你来说,如果我们假设这里的 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 } see spread operatorObject.assign() ),然后更新它以确保保留以前未更改的字段值。

关于node.js - 使用 mongoose 更新嵌套 json 文档中的一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60535282/

相关文章:

arrays - Mongoose - 填充二维数组

mongodb - 通过 Model.save() 更新时触发 Mongoose 预保存 Hook

MongoDB 自定义排序顺序,用于带分页的查询

mongodb - 将 Mongodb 卷挂载到 Azure Web App for Containers 中的 Azure 文件

mysql - 通过tunnel-ssh使用sequelize访问远程数据库时出错

node.js - 加密存储在环境变量中的密码

node.js - 在 Node 中使用 ES6 的更多功能(除了已发布的功能之外)(例如 "import/export")

scala - 从 scala 将文档插入 mongodb 时出错

java - 将数据从 MongoDB 加载到 HashMap

javascript - 服务器无法处理循环