【问题标题】:How to update only some properties of object in MongoDB database如何仅更新 MongoDB 数据库中对象的某些属性
【发布时间】:2018-01-14 08:02:04
【问题描述】:

我下面的代码不允许 API 用户通过传递一个请求属性来仅更新一个字段。我可以删除 userObj 处的空值,但 UI 开发人员必须从数据库中传递现有数据才能进行更新,这不是最佳做法。

这是我的特快路线:

router.put('/user', (req, res) => {
  const userObj = {
    name: req.body.name || null,
    location: {
      city: req.body.city || null
      },
      phone: req.body.phone || null
    };

  User.updateUser(req.body.id, userObj)
});

这是我的 Mongoose 模型的 updateUser 函数:

module.exports.updateUser = (_id, userObj, callback) => {
  User.findOneAndUpdate({_id}, userObj, { upsert: true, 'new': true }, callback);
}

【问题讨论】:

    标签: javascript node.js express mongoose ecmascript-6


    【解决方案1】:

    首先,要解决仅更新某些特定属性的问题,您必须使用$set 运算符仅设置特定字段。当您将userObj 直接传递给findOneAndUpdate 时,您将重置整个对象,因此您必须传递所有现有属性。使用$set

    User.findOneAndUpdate({_id}, { $set: userObj }, { upsert: true, new: true }, callback);
    

    这只会将userObj 中定义的属性更新为它们的新值,而不会触及其他任何东西。此外,对于这个用例,您可以只使用 findByIdAndUpdate

    User.findByIdAndUpdate(_id, { $set: userObj }, { upsert: true, new: true }, callback);
    

    接下来,您不应该使用 PUT。使用补丁。 PUT 意味着将资源放在某个 URL 上,如果它已经存在则完全替换它。 PATCH 意味着您只更新资源的几个属性,并替换整个内容。这不会影响应用的功能,但正如他们所期望的 PATCH 一样,这是一个巨大的语义问题和最终用户问题。

    【讨论】:

    • 所以使用 $set 和 findByIdAndUpdate 没有区别?
    • @JessieAnderson 有。如果您只想更新一个或多个特定属性,请始终使用$set,无论您使用findByIdAndUpdate 还是findOneAndUpdate
    • $set 不能解决问题。试了一下,我通过 {name: undefined, age: 10},现有的名字被覆盖了。
    • @JessieAnderson 如果您不想更新name,请不要传递name。只传入要覆盖的属性:{ age: 10 }
    【解决方案2】:

    使用$set

    User.findOneAndUpdate({_id}, {$set: userObj}, /* ... */)
    

    【讨论】:

      猜你喜欢
      • 2018-10-06
      • 2020-08-14
      • 1970-01-01
      • 2019-04-28
      • 2014-04-07
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多