【问题标题】:MongoDB update only changed fields in an object instead of replacing the whole objectMongoDB 仅更新对象中更改的字段,而不是替换整个对象
【发布时间】:2019-06-02 20:49:42
【问题描述】:

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

例如我在用户集合中有这个文档:

{
  _id: 1,
  date: new Date(),
  info: {
    first_name: "a",
    last_name: "b",
    phone: "c"
  }
}

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

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

{
  info: {
    first_name: "aa"
  }
}

现在为了只更新“info.first_name”并保留存储在 info ojbect 中的其他字段,我必须像这样设置更新查询:

db.users.update({}, {$set: {"info.first_name": req.body.info.first_name}}, cb);

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

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

$set: req.body

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

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

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

    读取数据库中的当前条目并将 req.body 分布在当前条目上不是更容易吗?

    // read current entry in database
    let currentObject = await user.findOne({_id});
    
    // merge current entry with changed updated key:values
    let newObject = ( currentObject, ...req.body );
    
    // write update to database
    let user.findOneAndUpdate({_id}, {$set: newObject}, )
    
    【解决方案2】:

    我也调查过,您不能将 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2020-05-20
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多