访问嵌套文档中的嵌套文档

时间:2018-04-09 14:47:44

标签: mongodb express mongoose nested-documents

我遇到了一个真正困扰我的问题。我甚至不想使用这个我想不到的解决方案,但我想知道是否有。

我正在使用mongodb和mongoose创建一个评论部分,并将评论附加到资源上,如下所示:

const MovieSchema = new mongoose.Schema({
  movieTitle: {type: String, text: true},
  year: Number,
  imdb: String,
  comments: [{
    date: Date,
    body: String
  }]
})

在编辑评论主体时,我知道我可以访问这样的嵌套文档:

const query = {
    imdb: req.body.movie.imdb,
    "comments._id": new ObjectId(req.body.editedComment._id)
}

const update = {
    $set: {
        "comments.$.body": req.body.newComment
    }
}

Movie.findOneAndUpdate(query, update, function(err, movie) {
    //do stuff
})

然后,我想推出对评论的第一级回复,其中对评论或其他回复的每个回复都只是作为顶级评论的回复数组(有点像Facebook,而不是像reddit)。起初我想保留对评论的回复,就像我保留了对资源的评论一样。因此架构看起来像这样:

const MovieSchema = new mongoose.Schema({
    movieTitle: {type: String, text: true},
    year: Number,
    imdb: String,
    comments: [{
        date: Date,
        body: String,
        replies: [{
            date: Date,
            body: String
        }]
    }]
})

我的问题是你将如何访问嵌套的嵌套文档。例如,如果我想编辑回复,我似乎不能使用两个$符号。那么我如何在mongodb中做到这一点,这甚至可能吗?

我很确定我会让评论有自己的模型来简化事情,但我仍然想知道这是否可行,因为如果不是mongodb似乎是一个相当大的缺点。另一方面,如果我没有弄清楚如何编辑嵌套的嵌套文档,我会觉得使用mongodb非常愚蠢...

1 个答案:

答案 0 :(得分:0)

根据这个问题:https://jira.mongodb.org/browse/SERVER-27089

更新嵌套嵌套元素可以这样做:

parent.update({}, 
    {$set: {“children.$[i].children.$[j].d”: nuValue}}, 
    { arrayFilters: [{ “i._id”: childId}, { “j._id”: grandchildId }] });

这包含在MongoDB 3.5.12开发版本中,在MongoDB 3.6生产版本中。

根据https://github.com/Automattic/mongoose/issues/5986#issuecomment-358065800它应该支持mongoose 5 +

如果你使用旧的mongodb或mongoose版本,有2种选择:

找到父母,编辑结果的孙子,保存父母。

const result = await parent.findById(parentId);

const grandchild = result.children.find(child => child._id.equals(childId))
    .children.find(grandchild => grandchild._id.equals(grandchildId));

grandchild.field = value;

parent.save();

知道granchild的索引"以某种方式",findByIdAndUpdate parent with:

parent.findByIdAndUpdate(id,
    { $set: { [`children.$.children.${index}.field`]: value }});