Mongoose仅更新已更改的值

时间:2017-07-03 13:26:41

标签: mongodb express mongoose routes

我有一条PUT路线来更新价值。我从两个地方来到这条路线。一个是发送有关详细信息的信息,另一个是关于已完成的信息。问题是mongoose正在更新booth,即使它只从一个获得价值。

因此,如果我发送有关已完成的信息是真的,后者我使用新的详细信息(没有完成的值)点击此路由,它将更新完成也为false。如何仅更新已更改的值?

router.put('/:id', (req, res) => {
  Todo.findOne({_id:req.body.id}, (err, foundObject) => {
      foundObject.details = req.body.details
      foundObject.completed = req.body.completed
    foundObject.save((e, updatedTodo) => {
      if(err) {
        res.status(400).send(e)
      } else {
        res.send(updatedTodo)
      }
    })
  })
})

修改 感谢杰克逊提示,我设法做到这一点。

router.put('/:id', (req, res) => {
  Todo.findOne({_id:req.body.id}, (err, foundObject) => {
    if(req.body.details !== undefined) {
      foundObject.details = req.body.details
    }
    if(req.body.completed !== undefined) {
      foundObject.completed = req.body.completed
    }
    foundObject.save((e, updatedTodo) => {
      if(err) {
        res.status(400).send(e)
      } else {
        res.send(updatedTodo)
      }
    })
  })
})

3 个答案:

答案 0 :(得分:1)

const updateQuery = {};

if (req.body.details) {
  updateQuery.details = req.body.details
}

if (req.body.completed) {
  updateQuery.completed = req.body.completed
}

//or
Todo.findOneAndUpdate({id: req.body.id}, updateQuery, {new: true}, (err, res) => {
  if (err) {

  } else {

  }
})

//or
Todo.findOneAndUpdate({id: req.body.id}, {$set: updateQuery}, {new: true}, (err, res) => {
  if (err) {

  } else {

  }
})

答案 1 :(得分:0)

具有与我的方法类似的功能

const _ = require('lodash');

router.put('/update/:id',(req,res, next)=>{
       todo.findById({
        _id: req.params.id
    }).then(user => {
        const obj = {
            new: true
        }
        user = _.extend(user, obj);
        user.save((error, result) => {
            if (error) {
                console.log("Status not Changed")
            } else {
                res.redirect('/')
            }
        })
    }).catch(error => {
        res.status(500);
    })
};

new:true 用作您要更新的值

答案 2 :(得分:0)

随着要更新的字段的增加,它有点难看。说100个字段。 我建议使用以下方法:

try {

    const schemaProperties = Object.keys(Todo.schema.paths)
    const requestKeys = Object.keys(req.body)
    const requestValues = Object.values(req.body)
    const updateQuery = {}

    // constructing dynamic query        
    for (let i = 0; i < requestKeys.length; i++) {
        // Only update valid fields according to Todo Schema
        if ( schemaProperties.includes(requestKeys[i]) ){
            updateQuery[requestKeys[i]] = requestValues[i]
        }
    }
    const updatedObject = await TOdo.updateOne(
        { _id:req.params.idd},
        { $set: updateQuery }
    );
    res.json(updatedObject)
} catch (error) {
    res.status(400).send({ message: error });
}