MongoDB,如果新值不为空,则更新集合字段



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

 ...
 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.*,我就可以解决问题。但这有可能吗?

你可以尝试这样的事情:

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 )
你可以

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

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

{b:1}

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

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

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

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

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

您可以通过将

req.body转换为模型来使用猫鼬,

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

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

没有猫鼬标签,但我强烈反对使用它。欲了解更多详情;

猫鼬更新

猫鼬模型

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

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

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

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

可能您已经进行了用户身份验证,因此您应该拥有 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
    }
})
let objForUpdate = {}
for (const key of Object.keys(req.body)) {
  if (req.body[key]) objForUpdate = Object.assign({}, objForUpdate, { [key]: req.body[key] })
} 
collection.update({_id:ObjectId(req.session.userID)}, { $set:  objForUpdate })

这将动态添加objForUpdate中的字段(如果在正文中定义)。

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

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

最新更新