0

我在 MongoDB 中有两个集合:一个保存博客的帖子数据,另一个保存具有以下模式的博客评论数据。如何使用 nodejs 和 mongoose 查询所有评论属于它的帖子并响应单页应用程序?谢谢!

var PostSchema = mongoose.Schema({
    created: {
        type: Date,
        default: Date.now
    },
    content: {
        type: String,
        default: '',
        trim: true
    },
    user: {
        type: Schema.ObjectId,
        ref: 'user'
    }
 }); 

 var CommentSchema = mongoose.Schema({
    created: {
        type: Date,
        default: Date.now
    },
    content: {
        type: String,
        default: '',
        trim: true
    },
    ofpost: {
        type: Schema.ObjectId, 
        ref: 'post'           //which post this comment belong to
    },
    user: {
        type: Schema.ObjectId,
        ref: 'user'
    }
 }); 




    var Post = mongoose.model('Post', PostSchema);
    var Comment = mongoose.model('Comment', CommentSchema); 

//example:the Comment1 and Comment2 belong to Post1
    var Post1 = new Post({ content: 'good day', user: 'John' });
    var Comment1 = new Comment({content: 'yeah', ofpost: Post1._id, user:'Tom'})
    var Comment2 = new Comment({content: 'agree', ofpost: Post1._id, user:'Tina'})
4

1 回答 1

1

由于 mongodb 是 NoSQL 类型的数据库,并且文档之间没有JOIN's 或任何类型的关系,因此您必须注意这一点。
通常有两种方法可以做到:

缓存
考虑在博客文档中存储评论数据。您可以毫无问题地嵌入文档。实际上,它会导致一些额外的缓存,例如评论计数、评论的用户 ID 数组和其他内容,这些内容将使您的查询被索引以及更简单的方法来搜索集合。

多个查询
如果您仍然需要单独的集合,那么您需要“模拟”连接。最有效的方法是对不同的集合进行临时索引数组和多个查询。通常对于一个 Join(多对多)应该只有 2 次查询,以及将第二个查询文档添加到第一个文档数组的小迭代。

以下是适合且表现良好的流程,例如:
两个集合,第一个是posts,第二个是commentspost id

  1. 对帖子进行查询。
  2. 遍历每个帖子并将其添加idpostIds数组中,以及将postMap对象key设置id为 post 并且value将是特定的post。- 这就是所谓的索引帖子。
  3. 使用带有帖子 ID 数组的参数对comments集合进行查询。该集合应该对 post id 字段进行索引,以使该查询非常有效。此查询还可以包括按日期排序(额外的复合索引将加速它)。$inpostIds
  4. 遍历每个评论并使用postMap将其添加到帖子的评论数组中。

所以我们只有 2 个查询,并且对所有评论进行一次迭代,以将数据嵌入帖子 O(n)。如果没有第二步,添加到帖子可能会是 O(p*c),其中 p - 帖子数和 c - 评论数。这显然要慢得多,大查询也可能很慢。

总结
第二种方法从数据的角度来看是更易于管理的方法,并且在 上更容易writes,而在 上更复杂reads
仍然需要一些缓存,例如博客文章的评论数量。

于 2013-09-24T13:44:34.710 回答