如何在MongoDB中的文档中存储高容量内部集合

时间:2014-04-12 15:05:31

标签: mongodb nosql

MongoDB对文档的限制是最大的。 16MB大小。但是,也鼓励将相关集合存储在文档中。例如,博客文章及其评论:

{
    _id: 1,
    title: "First Post",
    Content: "...",
    Comments: [
        { content: "..." },
        { content: "..." },
        ...
    ]
}

假设这篇文章已经病毒化,我收到了数百万条评论。我应该如何在MongoDB中存储评论?我应该将它放在具有以下结构的另一个集合中:

{
    _id: 23,
    blogPostId: 1,
    content: "..."
}

如果是这样的话,我该如何进行查询,例如"获取超过10条评论的博客文章"有效地执行?

2 个答案:

答案 0 :(得分:1)

这是MongoDB的一个常见用例,并在online manual中介绍。您通常有3个选择:

  1. 将每条评论存储在单独的文档中
  2. 将所有评论嵌入到父文档中(对16MB限制敏感)
  3. 混合设计,将注释与父项分开存储,但将注释聚合到少量文档(存储桶)中,每个文档包含许多注释
  4. 你可能还可以考虑另一种类型的混合,你可以在父文档的数组中存储最大数量的注释,然后可以在'comments overflow'集合中使用buksted注释,这只会被那些人使用已经传播病毒的帖子。实际上,只有很小比例的访问者会与Web应用程序进行交互,从而导致对溢出文档的查询。这是运行时效率与开发人员复杂性之间的权衡。

    对于大多数这些选项,您将在父文档中维护“预先聚合”的摘要数据(例如,评论总数),这将是您可以轻松查询的内容。预聚合也在online manual中讨论。

答案 1 :(得分:1)

好吧,我会寻求一个简单而有效的解决方案。让我们从查询的角度来看问题。大多数查询都对最近的评论感兴趣,对吗?我们同意在MongoDB中嵌入文档非常快速有效,但我们仅限于某个文档大小。因此,这里需要妥协。 我们可以嵌入最新的评论并参考其余的评论。

{
  _id : ObjectId(...),
  title : "Post title",
  most_recent_comments:[
  {
    commentBody :"...",
    author : "...",
  },
  {
    commentBody :"...",
    author : "...",
  },
  ],
  all_comments_ids :[ObjectId(commentId),ObjectId(commentId),ObjectId(commentId)]
}

因此,您可以为评论创建指定的collection,并将最新版本保留为嵌入式。根据您的计划,最近的评论可能是queue,您指定的尺寸有限。