MongoDB预聚合报告的模式设计

时间:2014-11-13 18:09:30

标签: mongodb reporting data-modeling

我正在关注有关预先汇总报告的官方MongoDB文档(http://docs.mongodb.org/ecosystem/use-cases/pre-aggregated-reports/)。根据教程,预先聚合的文档应如下所示:

{
  _id: "20101010/site-1/apache_pb.gif",
  metadata: {
    date: ISODate("2000-10-10T00:00:00Z"),
    site: "site-1",
    page: "/apache_pb.gif" },
  hourly: {
    "0": 227850,
    "1": 210231,
    ...
    "23": 20457 },
  minute: {
    "0": {
        "0": 3612,
        "1": 3241,
        ...
        "59": 2130 },
    "1": {
        "0": ...,
    },
    ...
    "23": {
        "59": 2819 }
  }
}

问题是我目前正在使用这种方法,并且我已经以这种方式存储了一些数据。但现在我想在元数据子文档中添加另一个维度,我正在重新考虑整个事情。

我的问题是:是否有理由使用存储在元数据属性中的相同信息构建_id属性?仅仅在元数据周围创建复合索引(唯一)并使用ObjectId作为_id键是不够的?

谢谢!

1 个答案:

答案 0 :(得分:0)

其他方式;)

您可以创建简单的集合:

{
  "ts": "unix timestamp",
  "site": "site-1",
  "page": "/apache_pb.gif"  
}

这个集合在插入

时会有很好的表现

并使用复杂的聚合查询(任何时候使用聚合):

db.test.aggregate(
[
  {
    "$project": {
      "ts": 1,
      "_id": 0,
      "grain": {
        "$subtract": [
          {
            "$divide": [
              "$ts",
              3600
            ]
          },
          {
            "$mod": [
              {
                "$divide": [
                  "$ts",
                  3600
                ]
              },
              1
            ]
          }
        ]
      },
      "site": 1,
      "page": 1
    }
  },
  {
    "$group": {
      "_id": {
        "site": "$site",
        "page": "$page",
        "grain": "$grain",
      }
    }
  },
  {
    "$group": {
      "tsum": {
        "$sum": 1
      },
      "_id": {
        "grain": "$_id.grain"
      }
    }
  },
  {
    "$project": {
      "tsum": "$tsum",
      "_id": 0,
      "grain": "$_id.grain"
    }
  },
  {
    "$sort": {
      "grain": 1
    }
  }
])

将您的统计信息汇总一小时 - 在此示例中为3600秒

imho - 这是一个更简单易管理的解决方案,没有复杂的数据模型,具有良好的性能(不要忘记索引)