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

11

只有当新值不为null时,我才会更新集合的设置。

我的代码如下:

 ...
 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 - tymeJV
这并不容易,我应该尝试所有的组合。 - Nicola
是否有超过3个变量? - tymeJV
是的,我在问题中剪切了一些代码。 - Nicola
10个回答

26

你可以尝试像这样做:

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 )

6
如果你有很多参数/字段,可能看起来不太好,最终可能会出现在 r/programminghorror 上。 - Fusseldieb

5

1
this is what i want - Bala

2
您是不是只是要把您发布的所有字段传递过来?那为什么不这样做呢?
(然后基本上只需复制并粘贴您的代码):
collection.update(
    {_id: ObjectId(req.session.userID)},
    {$set: req.body }
)

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

请注意,使用set仅会覆盖或添加新字段。如果您只想替换整个文档,则删除整个{$set:(...)}符号,并将请求正文作为有效对象传递。


1
不,这是一个数据用户表单编辑,因此未修改的字段无需修改... 这样我就用空白替换它们。 - Nicola

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

1
你可以使用mongoose来实现这个功能,方法是将req.body转换为你的模型对象。
我假设你已经有了一个名为User的mongoose模型,在你的控制器中实现。
var userModel = new User(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true}, function(err){
   console.log("Error occured!");
});

没有mongoose标签,但我强烈建议使用它。更多详情请参考;

Mongoose更新

Mongoose模型


在使用 Mongoose 时,您不需要手动转换为 ObjectId; 基于架构的转换是其关键优势之一。 - JohnnyHK

0

如果您不希望用户更改任何字段,可以使用以下方法。由于此方法将接受任何非空值并更新它,因此您可以这样做。

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

0
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中的字段。


0

可能你已经完成了用户认证,所以应该有 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
    }
})

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

-1
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 的问题。 - Teodor Sandu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接