考虑适合嵌套的博客/评论模式(即使您不同意):
var CommentSchema = new Schema({ name: String, body: String });
var BlogPostSchema = new Schema({ title: String, comments: [CommentSchema] });
我了解如何为博客帖子添加,更新和删除评论,但所有这些方法都需要在父博客帖子文档中调用save()
方法:
blog_post.comments.push( new Comment({...}) );
blog_post.save();
我希望能够让Comment模式知道它嵌套在另一个模式中,这样我就可以在评论文档上调用save()
,并且它足够聪明,可以更新父博客帖子。在我的应用程序逻辑中,我已经知道博客帖子ID,所以我想做这样的事情:
CommentSchema.virtual('blog_post_id');
CommentSchema.pre('save', function (next) {
var comment = this;
if( !comment.blog_post_id ) throw new Error('Need a blog post id');
BlogModel.findById( comment.blog_post_id, function(err, post) {
post.comments.push( comment );
post.save(next);
});
});
var comment = new Comment({ blog_post_id: 123, name: 'Joe', body: 'foo' });
comment.save();
上述工作,但我仍然最终得到一个与博客文章分开的顶级评论集(这就是mongoose的工作方式,我接受了)。
问题:如何阻止Mongoose创建单独的“评论”集合。在预保存方法中,我想调用next()
,之后不进行任何写操作。有什么想法吗?
答案 0 :(得分:2)
这为我赢得了Tumbleweed徽章......万岁!?!?
所以我写了很多代码来完成上面的工作。在我做更多测试之前,我不想发布它。但如果有人对此感兴趣,请在此处发帖告诉我。我很乐意交出我所拥有的(即将投入生产)。
现在我的代码不支持深度嵌套...这意味着你只能使用"简单"嵌套类似于上面的博客/评论示例。我有适当的架构来处理将来更复杂的嵌套,但我现在没有时间进行测试(最后期限)。以下是我目前解决方案的一些重点:
find
,findOne
,save
和remove
findById
没有(不能)工作 - 好吧可以工作但是需要搜索整个集合,这很慢。必须使用findOne
+父ID(参见示例)。Model.update()
在父模型上保存(这非常快)。// setup the "nestedSchema" plugin
var nestedSchema = require("./plugins/nestedSchema");
CommentSchema.plugin(nestedSchema, {
path: 'comments',
ownerModelPath: './BlogPostModel',
ownerIdFieldName: 'blogpost_id'
});
blogpost_id
总是被使用 - 这是一个要求它保持快速的要求(为简洁起见,删除了回调和错误处理):// create a new comment
var comment = new CommentModel({
blogpost_id: [id],
name: 'Joe Schmoe',
body: 'The content of the comment'
});
comment.save();
// use findOne in leu of findById
CommentModel.findOne({blogpost_id: [id], _id: [id]}, function( err, comment ) {
comment.set('body', 'This comment has been updated directly!');
comment.save();
});
// find all hateful comments and remove
CommentModel.find({blogpost_id: [id], body: /sucks|stupid|dumb/gi}).remove();
答案 1 :(得分:0)
使用https://www.npmjs.org/package/mongoose-relationship中的mongoose-relationship插件 可以使您的文档了解他们的关系。
添加/删除文档时,插件会更新相应的引用。
github页面上有一个很好的例子:https://github.com/sabymike/mongoose-relationship