使用Mongoose更新数组

时间:2016-11-16 20:57:01

标签: javascript node.js mongodb express mongoose

有一些关于此的帖子(例如herehere),但没有一个使用本机Mongoose方法。 (第一个使用$set,第二个使用extend npm包。看起来应该有一个“本地猫鼬”方式来做到这一点。

架构:

var blogPostSchema = new mongoose.Schema({
    title: String,
    comments: [{
        body: String
    }]
});

这是我最初尝试的内容:

BlogPost.findById(req.params.postId, function (err, post) {
    var subDoc = post.comments.id(req.params.commentId);
    subDoc = req.body;
    post.save(function (err) {
        if (err) return res.status(500).send(err);
        res.send(post);
    });
});

问题是这一行:subDoc = req.body实际上并没有改变父文档的subDoc,而只是通过引用传递。 save()调用后,数据库中实际上没有任何变化。

extend程序包通过将两个对象合并在一起来修复此问题,如上面链接的第二个SO帖子所示(并再次here)。但是,有没有办法使用一些Mongoose API方法解决这个问题?我在文档中找不到任何关于它的东西(只有如何添加新的subdocs和删除subdocs)。

我写的另一个选择是:

for (var key in subDoc) {
    subDoc[key] = req.body[key] || subDoc[key];
}

这也有效,但我不确定这样做是否有任何危险。也许这是最好的方式?

提前致谢!

1 个答案:

答案 0 :(得分:8)

subDoc = req.body无法正常工作的原因是它正在使用subDoc的全新引用将第一次分配所创建的引用替换为req.body(假设它是一个对象,而不是一个字符串)。这与Mongoose无关,而只是参考文章的工作原理。



var objA = { a: 1, b: 2};
var objB = { a: 'A', b: 'B'};

var objC = objA;
console.log('Assigning ref to objC from objA', {objA, objB, objC});
// It should console.log the following:
// Assigning ref to objC from objA {
//   "objA": {
//     /**id:2**/
//     "a": 1,
//     "b": 2
//   },
//   "objB": {
//     "a": "A",
//     "b": "B"
//   },
//   "objC": /**ref:2**/
// }
//

objC = objB;            
console.log('Replacing ref to objC with objB', {objA, objB, objC});
// It should console.log the following:
// Replacing ref to objC with objB {
//   "objA": {
//     "a": 1,
//     "b": 2
//   },
//   "objB": {
//     /**id:3**/
//     "a": "A",
//     "b": "B"
//   },
//   "objC": /**ref:3**/
// }




您可以使用Document.#set method。只需为它提供一个对象(在本例中为req.body),该对象使用您要设置的值镜像文档的结构。

BlogPost.findById(req.params.postId, function(err, post) {
  var subDoc = post.comments.id(req.params.commentId);
  subDoc.set(req.body);

  // Using a promise rather than a callback
  post.save().then(function(savedPost) {
    res.send(savedPost);
  }).catch(function(err) {
    res.status(500).send(err);
  });
});