使用 findOneAndUpdate() 时,如果没有提供值,如何保持字段不变(而不是用 null 覆盖)?

Posted

技术标签:

【中文标题】使用 findOneAndUpdate() 时,如果没有提供值,如何保持字段不变(而不是用 null 覆盖)?【英文标题】:When using findOneAndUpdate(), how to leave fields as is if no value provided (instead of overwriting with null)? 【发布时间】:2018-06-01 07:40:06 【问题描述】:

用户可以选择更新几个值中的任何一个 - 但是,如果他只传入 name: "new name" ,则电子邮件和密码字段也会更新,但会更新为“null”。

我怎样才能只更新 req.body 中实际提供的字段,而将其余部分保持原样?

这是在指定可以使用 POST 请求更新哪些字段的同时 - 我已经避免只传入 req.body ,因为我想限制这一点。

我的代码如下:

db.User.findOneAndUpdate(_id: req.params.id,  
        name: req.body.name,
        email: req.body.emaill, 
        password: req.body.password
)

使用类似名称:req.body.name && req.body.name 来检查值是否未定义也会被“null”覆盖。

谢谢!

【问题讨论】:

【参考方案1】:

首先准备你的更新对象:

let params =  
        name: req.body.name,
        email: req.body.emaill, 
        password: req.body.password
;

for(let prop in params) if(!params[prop]) delete params[prop]; //This will not handle intentionally setting to false, empty string, null, 0, or other falsey values.

db.User.findOneAndUpdate(_id: req.params.id, params);

或者,如果您的属性名称匹配:

let params = ;

for(let prop in req.body) if(req.body[prop]) params[prop] = req.body[prop];

db.User.findOneAndUpdate(_id: req.params.id, params);

【讨论】:

第二行的params 后面的. 是错字吗? 这一行?:db.User.findOneAndUpdate(_id: req.params.id, params); for(let prop in req.body) if ... params.[prop] = ... 行。我说的是params[prop]之间的. @N-ate 这个语法叫做“for (let empty in params) if (!params[empty]) delete params[empty];” ?? 通常称为for/in。 w3schools.com/jsref/….【参考方案2】:

这个怎么样?

db.User.findOneAndUpdate(_id: req.params.id, req.body)

如果您的请求与您的示例 ( name: "new name" ) 中的完全一样,那么这应该会产生预期的效果。

【讨论】:

我想通过将其编码到服务器而不是客户端来限制可以更新的值 - 否则也许有人可以手动发送一些发布请求来更新不打算更新的值。 【参考方案3】:

如果您计划验证收到的数据,您可以创建包含所有有效字段的更新对象。例如:

// Example post
const req = 
    body: 
        name: "First Last",
        email: "app@app.com",
        somethingElse: "I snuck in another update!"
    


// Create update obj
const update = 

// Destrcture the body to make if statments smaller to read
const name,email,password = req.body

// Test all values and add valide ones to update
if(name !== undefined && typeof name === 'string') 
    update.name = name


if(email !== undefined && typeof name === 'string') 
    update.email = email


if(password !== undefined && typeof password === 'string') 
    update.password = password


console.log(update)

现在在 Mongo 更新中使用该更新对象。当然,您希望调整验证以检查电子邮件格式或密码要求等内容,并且可能更清洁以将它们放入函数中,但您明白了。

【讨论】:

【参考方案4】:

const resu=await this.store.company.findByIdAndUpdate(companyId, $set: name,dba,description,foundedYear,contactInfo,clients,eVerified,socialMedia , , new:true,omitUndefined:true,)

使用 omitUndefined:true 选项

【讨论】:

以上是关于使用 findOneAndUpdate() 时,如果没有提供值,如何保持字段不变(而不是用 null 覆盖)?的主要内容,如果未能解决你的问题,请参考以下文章

当我使用Model.findOneAndUpdate时,不会调用用于保存和更新的猫鼬预钩子

mongodb findOneAndUpdate 只获取更新的字段

猫鼬 findOneAndUpdate 和 runValidators 不工作

猫鼬 findOneAndUpdate 和 runValidators 不工作

猫鼬 findOneAndUpdate 不更新

Mongoose findOneAndUpdate 不会更新我的数据库