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