查询mongodb数据库结构的多对多关系

时间:2013-09-24 03:48:57

标签: node.js many-to-many schema mongoose single-page-application

我在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'})

1 个答案:

答案 0 :(得分:1)

由于mongodb是NoSQL类型的数据库,并且文档之间没有JOIN或任何关系,因此您必须处理此类问题。
通常有两种方法:

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

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

以下是适合并且表现良好的流程,例如:
两个集合,第一个是posts,第二个是comments,其中有id个帖子。

  1. 查询帖子。
  2. 遍历每个帖子并将其id添加到postIds数组中,并将postMap对象key添加到id的帖子和{{} 1}}将是具体的value。 - 这就是所谓的索引帖子。
  3. 使用post参数comments$in集合进行查询。此集合应该在post id字段上建立索引,以使此查询非常有效。此查询还可以包括按日期排序(额外的复合索引将加速它)。
  4. 仔细检查每条评论,然后使用postIds将其添加到帖子的评论数组中。
  5. 因此,我们只有2个查询,并且通过所有注释迭代一次以将数据嵌入到帖子O(n)中。如果没有第二步,添加到帖子可能是O(p * c),其中p - 帖子数量和c - 评论数量。对于大型查询来说,这显然要慢很多。

    <强>摘要
    从数据的角度来看,第二种方法是更易于管理的方法,postMap更容易处理,而writes则更复杂。 仍需要一些缓存,例如博客帖子的评论数量。

相关问题