我遇到了一个真正困扰我的问题。我甚至不想使用这个我想不到的解决方案,但我想知道是否有。
我正在使用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非常愚蠢...
答案 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 }});