【问题标题】:MongoDB, update collection field if new value is not nullMongoDB,如果新值不为空,则更新集合字段
【发布时间】:2014-03-31 01:18:41
【问题描述】:

仅当新值不为空时,我才会更新设置值的集合。 我有这样的代码:

 ...
 var userName = req.body.nome;
 var userSurname = req.body.cognome;
 var userAddress = req.body.indirizzo;

 collection.update(
     {_id:ObjectId(req.session.userID)},
     {$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
 )

有没有简单的方法可以做到这一点?

另一种方式: 如果我可以从获取数据的表单的占位符中获取值req.body.*,我可以解决问题..但这可能吗?

【问题讨论】:

  • 只是运行检查if (userName != null && ... ) //db update
  • 这不容易,我应该尝试所有的组合
  • 变量是否超过 3 个?
  • 是的,我删了一些代码的问题

标签: javascript node.js mongodb


【解决方案1】:

你可以试试这样的:

var objForUpdate = {};

if (req.body.nome) objForUpdate.nome = req.body.nome;
if (req.body.cognome) objForUpdate.cognome = req.body.cognome;
if (req.body.indirizzo) objForUpdate.indirizzo = req.body.indirizzo;

//before edit- There is no need for creating a new variable
//var setObj = { $set: objForUpdate }

objForUpdate = { $set: objForUpdate }

collection.update({_id:ObjectId(req.session.userID)}, objForUpdate )

【讨论】:

  • 如果你有很多参数/字段,它可能看起来不太好,你最终会陷入 r/programminghorror
【解决方案2】:

可能您已经通过了用户身份验证,因此您应该拥有 req.user.*

在这种情况下,您可以使用三元运算符来分配值并使用新值或当前值更新它(因此没有更新)

var userName = req.body.nome ? req.body.nome : req.user.nome;
var userSurname = req.body.cognome ? req.body.nome : req.user.cognome;
var userAddress = req.body.indirizzo ? req.body.indirizzo : req.user.indirizzo;

collection.update(
     {_id:ObjectID(req.session.userID)},
     {$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
)

如果您没有 req.user,那么您可以分 3 步完成。 1. 在集合中查找用户 2.获取当前数据 3. 用新的或当前的(如上)更新数据

let currentName
let currentSurname
db. collection.findOne({_id: ObjectID(req.session.userID)}, (err, user) => {
    if (err) { } // handle error here
    else if (user) {
        currentName = user.name
        currentSurname = user.surname
    }
})

【讨论】:

    【解决方案3】:

    此版本仍允许尊重和更新空字符串字段。省略的字段将被忽略。

    const cleanedObject = Object.keys(origObject).reduce((acc, k) => {
      if (typeof origObject[k] === "undefined") return acc;
      acc[k] = origObject[k];
      return acc;
    }, {});
    
    collection.update({_id:ObjectId(req.session.userID)}, cleanedObject })
    

    【讨论】:

      【解决方案4】:

      如果没有您不希望用户能够更改的任何字段。因为此方法将采用任何非空值并对其进行更新。你可以这样做。

       const updatedFields = {};
       Object.keys(req.body).forEach(key => {
         if (!isEmpty(req.body[key])) {
           updatedFields[key] = req.body[key];
         }
       });
      YourModel.findOneAndUpdate(
            { employee_id: req.body.employee_id },
            {$set:updatedFields},
            {new:true}).then(updatedObj =>{
              console.log("updated obj:",updatedObj);
            })
      

      是空函数

          const isEmpty = value =>
        value === undefined ||
        value === null ||
        (typeof value === "object" && Object.keys(value).length === 0) ||
        (typeof value === "string" && value.trim().length === 0);
      

      【讨论】:

        【解决方案5】:

        您可以像其他问题一样使用 lodash:https://stackoverflow.com/a/33432857/4777292

        _.pickBy({ a: null, b: 1, c: undefined }, _.identity);

        {b:1}

        【讨论】:

        • 这就是我想要的
        【解决方案6】:

        Hüseyin BABAL 的答案在正确的轨道上,但这会产生来自 mongo 的警告,因为调用 new User() 将创建一个新的 _id,它是不可变的。您要做的是:

        const userModel = Object.assign(req.body);
        User.update({_id: req.session.userID}, userModel, {upsert: true}, 
          function(err){
            console.log("Error occured!");
          });
        

        【讨论】:

        • 不,因为这仍然会覆盖任何具有空值的字段,所以它不能解决 OP 的问题。
        【解决方案7】:

        您可以通过将req.body 投射到您的模型来使用猫鼬,

        我假设您有名为 User 的猫鼬模型,并且在您的控制器中,

        var userModel = new User(req.body);
        User.update({_id: req.session.userID}, userModel, {upsert: true}, function(err){
           console.log("Error occured!");
        });
        

        没有猫鼬标签,但我强烈建议使用它。更多详情;

        Mongoose Update

        Mongoose Model

        【讨论】:

        • 使用Mongoose时不需要手动转换为ObjectId;基于模式的强制转换是主要优势之一。
        【解决方案8】:

        您不只是要求传递您发布的所有字段吗?那为什么不这样做呢?

        (基本上只是您的代码的剪切和粘贴):

        collection.update(
            {_id: ObjectId(req.session.userID)},
            {$set: req.body }
        )
        

        然后,您发布为字段的任何内容都会在您的更新中设置。

        请注意,使用 set 会覆盖或添加新字段。如果您只想替换整个文档,请删除整个 {$set: (..) } 表示法并传入 req 正文,因为它是一个有效对象。

        【讨论】:

        • 不,这是一个数据用户表单编辑,所以不是modifield的字段没有被修改..这样我什么都没有替换它们
        猜你喜欢
        • 2019-05-02
        • 2020-04-10
        • 2012-10-29
        • 1970-01-01
        • 2021-04-24
        • 2019-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多