MongoDB 仅更新对象中更改的字段,而不是替换整个对象

Raz*_*Raz 7 mongodb node.js

我想更新 MongoDB 中包含对象的文档。由于更新的对象是由用户给出的,我不知道他到底要改变什么。

例如,我在用户集合中有此文档:

{
  _id: 1,
  date: new Date(),
  info: {
    first_name: "a",
    last_name: "b",
    phone: "c"
  }
}
Run Code Online (Sandbox Code Playgroud)

用户可以编辑名字和姓氏,但不能编辑电话。

这是req.body(我从用户那里收到的输入):

{
  info: {
    first_name: "aa"
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,为了仅更新“info.first_name”并保留存储在 info ojbect 中的其他字段,我必须设置一个更新查询,如下所示:

db.users.update({}, {$set: {"info.first_name": req.body.info.first_name}}, cb);
Run Code Online (Sandbox Code Playgroud)

但输入可以是动态且可变的。我不知道是否总是更新的名字,它可以是姓氏,甚至是其他子对象,例如地址:“info.address.city”(例如)

因此,我像这样处理这些更新:

$set: req.body
Run Code Online (Sandbox Code Playgroud)

就是这样。它有效,但我对此有疑问。它替换了整个信息对象,并且不保留存储在其中的其他密钥 - 电话被删除,姓氏被删除。

有没有办法告诉 MongoDB 不要替换整个对象,而只是更新那些提到的键?

aud*_*ick 0

我也研究过它,你不能将 mongo 设置为仅更新特定字段。您可以做的是根据输入动态构建查询。

我通常循环遍历输入,然后验证允许修改的内容,并基于此构建动态查询:

var updateQuery = {};
for(key of req.body.info) {
    if (req.body.info.hasOwnProperty(key) && canBeModified(key)) //this would be a function to validate what can be updated
        updateQuery['info.' + key] = req.body.info[key]};
}
db.users.update({}, {$set: updateQuery}, cb);
Run Code Online (Sandbox Code Playgroud)