用猫鼬更新许多属性的优雅方法

时间:2019-10-25 19:28:25

标签: javascript node.js mongodb mongoose

我有一个具有7个属性的模型,并且想要在前端发出编辑请求时全部更新它们。有什么优雅的方法可以做到这一点,还是我必须像在下面的代码中手动键入它们一样(顺便说一下对我来说很好,但是看起来很丑)。

exports.saveDish = (req, res, next) => {
  const {
    name,
    description,
    price,
    category,
    vegetarian,
    hot,
    menuPosition,
  } = req.body;
  Dish.findById(req.body._id)
    .then(oldDish => {
      if (oldDish) {
        oldDish.name = name;
        oldDish.description = description;
        oldDish.price = price;
        oldDish.category = category;
        oldDish.vegetarian = vegetarian;
        oldDish.hot = hot;
        oldDish.menuPosition = menuPosition;
        oldDish.save();
        return res.status(204).json({ message: 'Dish data properly updated' });
      }
      const newDish = new Dish(req.body);
      newDish.save();
      return res.status(201).json({ message: 'New dish properly saved' });
    })
    .catch(err => console.log(err));
};

3 个答案:

答案 0 :(得分:1)

这将更新现有记录并返回更新的值。如果没有找到匹配的记录,它将返回一个虚假的值到回调或Promise(不记得它是null还是其他东西)。

Dish.findByIdAndUpdate(req.body._id, updates, {new: true}, cb)

答案 1 :(得分:1)

您可以尝试这样的事情:

exports.saveDish = (req, res, next) => {

    /**
     * 
     * upsert: true --> helps to insert new document if no matching doc exists
     * new: true --> returns new document in output
     * rawResult: true --> helps to find out whether update or insert operation is done 
     * 
     * Dish is a mongoose schema where findByIdAndUpdate is only from mongoose,
     * which internally converts a string from it's first parameter into {_id : ObjectId('req.body._id')}, also uses $set operation on req.body
     *
     * Print data to check what's being returned, you might see entire document(data.value) being returned with some other information
     *
     * */

    Dish.findByIdAndUpdate(req.body._id, req.body, { upsert: true, new: true, rawResult: true }, (err, data) => {
        if (err) { console.log(err); res.status(200).json({ message: 'Operation Failed' }) }
        if (data.lastErrorObject.updatedExisting) return res.status(204).json({ message: 'Dish data properly updated' });
        return res.status(201).json({ message: 'New dish properly saved' });
    })
};

如果您在数据库中找不到匹配的_id,则在这里您要更新现有文档(添加新字段或使用req.body更新现有字段)或插入整个新文档。多个数据库调用。在这里,我已经在回调函数中实现了它,但是更早之前,我实际上是在async await中完成了它,无论哪种方式都可以工作,这应该适用于上面列出的所有情况! >

参考: Mongoose findByIdAndUpdate

答案 2 :(得分:0)

@EddieDean,您的方法几乎可以正常工作,事实证明,您必须传递任何id到findByIdAndUpdate()方法,所以我也对其进行了一点编辑,以便也可以使用独特的新菜。

工作代码以防万一:

exports.saveDish = (req, res, next) => {
  if (req.body._id) {
    Dish.findByIdAndUpdate(
      { _id: req.body._id },
      { ...req.body },
      { useFindAndModify: false }
    )
      .then(oldDish => {
        if (oldDish) {
          oldDish.save();
          return res
            .status(204)
            .json({ message: 'Dish data properly updated' });
        }
      })
      .catch(err => console.log(err));
  } else {
    const newDish = new Dish(req.body);
    newDish
      .save()
      .then(result => {
        return res.status(201).json({ message: 'New dish properly saved' });
      })
      .catch(err => console.log(err));
  }
};