Node.js Nodejs findOneAndUpdate参数器
我有一个具有以下模式的用户模型,所有字段都是必需的Node.js Nodejs findOneAndUpdate参数器,node.js,mongoose,Node.js,Mongoose,我有一个具有以下模式的用户模型,所有字段都是必需的 name:String, country:String, age:Number 从前端我按下更新按钮,只更新年龄字段,在后端我有以下内容 var body = _.pick(req.body, ["candidateId","name","age","country"]); var candidateId = mongoose.Types.ObjectId(body.candidateId); Candidate.findOneAndUp
name:String,
country:String,
age:Number
从前端我按下更新按钮,只更新年龄字段,在后端我有以下内容
var body = _.pick(req.body, ["candidateId","name","age","country"]);
var candidateId = mongoose.Types.ObjectId(body.candidateId);
Candidate.findOneAndUpdate({
_id:candidateId
},{
name: body.name,
country: body.country,
age: body.age,
}).then((data) => {
if (!data) {
res.status(400).send('noDataFound');
} else {
res.status(200).send(data);
}
}).catch((e) => {
res.status(500).send(e)
})
Front按如下方式传递数据
{ "candidateId":"5a9a86c16acff45a8070d2da",
"name":"Superman",
}
我将得到body.age和body.country的未定义错误,因为它不是从前端传递的
问题-如果某个参数的前端未发送任何值,如何使用以前的值,一种方法是即使未更改也发送所有值。形成一个包含已发送值的新对象:
const newObj = {};
if (body.name) {
newObj.name = body.name;
}
if (body.age) {
newObj.age = body.age;
}
if (body.country) {
newObj.country = body.country;
}
然后使用newObj
进行更新
Candidate.findOneAndUpdate({
_id:candidateId
}, newObj)...
当我遇到这个问题时,我通常创建一个解析器函数,如下所示:
var body = _.pick(req.body, ["candidateId","name","age","country"]);
var candidateId = mongoose.Types.ObjectId(body.candidateId);
function createUpdatedValues(params) {
var condition = {};
if (params.candidateId) condition.candidateId = params.candidateId;
if (params.name) condition.name = params.name;
if (params.age) condition.age = params.age;
if (params.country) condition.country = params.country;
return condition;
}
Candidate.findOneAndUpdate({
_id:candidateId
},createUpdatedValues(body)).then((data) => {
if (!data) {
res.status(400).send('noDataFound');
} else {
res.status(200).send(data);
}
}).catch((e) => {
res.status(500).send(e)
})
看起来您正在使用lodash,请签出以删除未定义或空属性:
_.omitBy({ foo: 'foo', bar: undefined, baz: null }, _.isNil)
{foo: "foo"}
下面是一个普通的JS解决方案:
Object
.entries({ foo: 'foo', bar: undefined, baz: null })
.filter(([_, value]) => value !== null && value !== undefined)
.reduce((acc, [key, value]) => { acc[key] = value; return acc; }, {})
我用下面的方法来解决这个问题,如果还有其他更好的方法,请告诉我,我会把它作为答案 我现在将所有要从前端更新的数据传递到一个新对象中,如下所示 ---客户端数据-- ----更新逻辑----
我没有用猫鼬,所以我有个问题。您能否只更新找到的对象的
name
值?我可以更新所有内容,但前端也必须发送所有旧数据。。我想要一种前端只传递新数据的方法。我想问的是,您能否使用findOneAndUpdate
有选择地更新已找到对象的字段?或者是否需要为找到的对象的每个字段指定一个值?是可以做到这一点。findOneAndUpdate基本上需要一对键值来更新。。但我有很多价值观要提交15-20,所以这很快就会变得不整洁。。。还有别的办法吗?我可以考虑的一种方法是获取当前数据并执行合并,然后更新数据..但问题是时间增加了,因为再次必须从DB获取数据并合并..是的,您可以使用findOne获取此对象,使用新值更新它,然后使用findOneAndUpdate,我不推荐使用findOneAndUpdate,因为它需要更长的时间
{ "candidateId":"5a9a86c16acff45a8070d2da",
"updatedData":{
"firstName":"Jack",
"lastName":"Bauer",
"applicationSource":"consultant",
"skills":["trading","sales"]
}
}
var body = _.pick(req.body, ["candidateId","updatedData"]);
var candidateId = mongoose.Types.ObjectId(body.candidateId);
var dataToUpdate = _.pick(body.updatedData,["firstName","lastName"]);
Candidate.findOneAndUpdate({
_id:candidateId
},dataToUpdate).then((data) => {
if (!data) {
res.status(400).send('noDataFound');
} else {
res.status(200).send(data);
}
}).catch((e) => {
res.status(500).send(e)
})