【问题标题】:How to store high volume inner collections inside a document in MongoDB如何在 MongoDB 的文档中存储大量内部集合
【发布时间】:2014-05-26 18:13:31
【问题描述】:

MongoDB 对文档有最大限制。 16MB 大小。但是,也鼓励将相关集合存储在文档中。例如,一篇博文及其 cmets:

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

假设这篇文章已经传播开来,并且我收到了数百万的 cmets。我应该如何将 cmets 存储在 MongoDB 中?我应该把它放在另一个具有以下结构的集合中:

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

如果是这种情况,我应该如何让诸如“获取超过 10 个 cmets 的博客文章”之类的查询高效执行?

【问题讨论】:

  • 鼓励将相关的集合/关系存储为适合的子文档。如果您的卷关系很高,则它是不适合子文档的条款之一

标签: mongodb nosql


【解决方案1】:

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

  1. 将每条评论存储在单独的文档中
  2. 在父文档中嵌入所有 cmets(注意 16MB 限制)
  3. 混合设计,将 cmets 与父级分开存储,但将 cmets 聚合到少量文档(桶)中,其中每个文档包含许多 cmets

您可能还可以考虑另一种类型的混合,其中您将最大数量的 cmets 存储在父文档的数组中,然后可能在“cmets 溢出”集合中使用分桶 cmets,它只会被那些使用已经病毒式传播的帖子。实际上,只有一小部分访问者会与 Web 应用程序交互以导致对溢出文档的查询。这是运行时效率与开发人员复杂性之间的某种权衡。

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

【讨论】:

    【解决方案2】:

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

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

    因此,您可以为 cmets 创建一个指定的 collection 并将最新的保留为 embedded 。从您的程序中,最近的 cmets 可能是您指定的有限大小的 queue。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-09
      • 1970-01-01
      • 2012-06-26
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多