使用mongoose从请求正文更新嵌入式文档

时间:2015-10-15 18:03:33

标签: node.js mongodb mongoose

我疯狂地试图找出一种用Mongoose完成这么简单任务的有效方法。

我有一个Customer和Dog Schema,Dogs嵌入在Customer文档中。然后,我将更新的Dog对象PUT到服务器,并尝试使用以下代码更新匹配的嵌入对象。

Customer.findById(req.params.cust_id).exec(function(err, customer) {
            if (err) return next(err);
            var dog = customer.dogs.id(req.params.dog_id)
            dog.update(req.body, function(err, dog) {
                if (err) return next(err);
                res.json({
                    message: 'Dog updated.'
                });
            });
        });

这给了我错误" #update方法在EmbeddedDocuments"上不可用。好,可以。因此,由于我无法调用update来将请求主体与要更新的文档合并,因此使用请求主体(更新后的狗)有效更新整个文档(基本上是合并)的替代方法是什么。

我不想输出要更新的每个属性。

更新

按照Sam的建议,通过NPM安装lodash之后,这个解决方案对我有用了!

Customer.findById(req.params.cust_id).exec(function(err, customer) {
            if (err) return next(err);

            var dog = customer.dogs.id(req.params.dog_id)
            _.merge(dog, req.body);

            customer.save(function(err, customer) {
                if (err) return next(err);
                res.json({
                    message: 'Dog updated.'
                });
            });
        });

1 个答案:

答案 0 :(得分:3)

这里的问题是你的变量狗没有用任何mongoose方法包裹,因为mongoose只包装主文件。

你可以通过使用一个名为lodash的小库

来实现这一目标 像这样:

var _ = require('lodash');
exports.update = function(req, res) { 
if(req.body._id) { delete req.body._id; }
  Customer.findById(req.params.id, function (err, customer) {
    if (err) { return handleError(res, err); }
    if(!customer) { return res.send(404); }
    var updated = _.merge(customer, req.body); // lodash merge method update matching fields with the new value
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, customer);
    });
  });
};

如果它不按您想要的方式工作,请查看lodash文档,并尝试通过_.extend或_.assign

更改_.merge

实现此目的的另一种方法是使用运算符$ addToSet

take a look at the mongo documentation

希望这有帮助!