4

由于我们可以以任何我们想要的方式构建 MongoDB,我们可以这样做

{ products:
  [
    { date: "2010-09-08", data: { pageviews: 23, timeOnPage: 178 }},
    { date: "2010-09-09", data: { pageviews: 36, timeOnPage: 202 }}
  ],
  brands:
  [
    { date: "2010-09-08", data: { pageviews: 123, timeOnPage: 210 }},
    { date: "2010-09-09", data: { pageviews: 61, timeOnPage: 876 }}
  ]
}

因此随着我们日复一日地向它添加数据,products文档和brands文档将变得越来越大。products3年后,中和中将有一千个元素brands。对 MongoDB 不好吗?我们是否应该将其分解为 4 个文档:

{ type: 'products', date: "2010-09-08", data: { pageviews: 23, timeOnPage: 178 }}
{ type: 'products', date: "2010-09-09", data: { pageviews: 36, timeOnPage: 202 }}
{ type: 'brands', date: "2010-09-08", data: { pageviews: 123, timeOnPage: 210 }}
{ type: 'brands', date: "2010-09-08", data: { pageviews: 61, timeOnPage: 876 }}

那么3年后,只有2000份“文件”?

4

5 回答 5

2

假设您使用的是 Mongoid(您对其进行了标记),您不会想使用您的第一个架构想法。每次你想查找一个小值时,Mongoid 都拉出那些巨大的文档是非常低效的。

对您来说可能更好的模型是:

class Log
  include Mongoid::Document

  field :type
  field :date
  field :pageviews,    :type => Integer
  field :time_on_page, :type => Integer
end

这将为您提供如下所示的文档:

{_id: ..., date: '2010-09-08', type: 'products', pageviews: 23, time_on_page: 178}

不用担心文档的数量——Mongo 可以处理数十亿的文档。您可以索引类型和日期以轻松找到您想要的任何数字。

此外,这种方式更容易通过驱动程序更新记录,甚至无需从数据库中提取记录。例如,在每次网页浏览中,您可以执行以下操作:

Log.collection.update({'type' => 'products', 'date' => '2010-09-08'}, {'$inc' => {'pageview' => 1}})
于 2010-09-11T02:18:46.257 回答
1

我不是 MongoDB 专家,但 1000 并不是“巨大的”。此外,我会严重怀疑包含 4000 个子元素的 1 个顶级文档和每个包含 1000 个子元素的 4 个顶级文档之间的任何区别——其中一个是六个之一,另一个是六个另一个问题。

现在,如果您谈论的是 1 个包含 1,000,000 个元素的文档与 1000 个包含 1000 个元素的文档,那是一个不同的数量级 + 可能在存储时间或查询时间上两者都有优势。

于 2010-09-11T00:40:01.167 回答
0

您的设计似乎与关系表模式非常相似。

替代文字

因此,添加的每个文档都将是集合中的一个单独条目,具有自己的标识符。虽然 mongo 文档大小限制为 4 MB,但它基本上足以容纳纯文本文档。而且您不必担心 mongo 中不断增长的文档数量,这就是基于文档的数据库的本质。

您唯一需要担心的是数据库集合的大小。对于 32 位系统,它限制为 2GB。因为 MongoDB 使用内存映射文件,因为它们与可用内存寻址相关联。这不是 64 位系统的问题。

希望这可以帮助

于 2010-09-14T13:30:10.357 回答
0

您已经讨论了如何更新数据,但您打算如何查询它?它可能会对您应该如何构建文档产生影响。

在数组中使用嵌入元素的问题在于,每次添加它时,它可能不适合为文档分配的当前空间。这将导致(新)文档被重新分配和移动(该移动将需要重新编写文档的任何索引)。

我通常会建议您建议的第二种形式,但这取决于上述问题。

注意:4MB 是任意限制,很快就会提高;实际上,您可以重新编译服务器以获得您想要的任何限制。

于 2010-09-12T20:37:49.850 回答
0

同样,这取决于您的查询用例。如果你真的很在意单品,比如每天的产品:

{类型:'产品',日期:“2010-09-08”,数据:{浏览量:23,timeOnPage:178}}

那么您可以在一个日期中包含多天。

{ type: 'products', { date: "2010-09-08", data: { pageviews: 23, timeOnPage: 178 } } }

我们使用这样的东西:

{类型:'产品',“2010”:{“09”:{“08”:数据:{浏览量:23,timeOnPage:178}}}}}

所以我们可以按天递增: { "$inc" : { "2010.09.08.data.pageviews" : 1 } }

也许看起来很复杂,但优点是您可以将有关“类型”的所有数据存储在 1 条记录中。因此,您可以检索一条记录并拥有所有信息。

于 2010-09-15T19:17:45.450 回答