1

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

我正在使用 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 中做到这一点,这甚至可能吗?

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

4

1 回答 1

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();

知道孙子的索引“不知何故”, findByIdAndUpdate 父母:

parent.findByIdAndUpdate(id,
    { $set: { [`children.$.children.${index}.field`]: value }});
于 2018-04-09T16:19:26.110 回答