MongoDB数据模型,支持每个事件,每个日期范围的唯一访问者

时间:2012-10-24 12:44:35

标签: java mongodb aggregation-framework

我有多个网站,每个网站都有访问者“触发”我要跟踪的多个事件。我从所有网站上都记录了这些事件,每个事件都填充了网站ID,事件名称和执行事件的用户ID(为了简单起见,我们就是这样)。

要求:

  1. 根据网站ID和事件名称,能够获得有多少唯一身份访问者。
  2. 这也应该支持日期范围(范围内的独特访客)。
  3. 我正在考虑使用以下数据模型(例如)为每个“website-id”创建一个集合:

    collection ev_{websiteId}:
    [
        {
            _id: "error"
            dailyStats: [
                {
                    _id: 20121005 <-- (yyyyMMdd int, should be indexed!)
                    hits: 5
                    users: [ 
                             {
                                _id: 1, <-- should be indexed!
                                hits: 1
                             }, 
                             {
                                _id: 2
                                hits: 3
                             },
                             {
                                _id: 3,
                                hits: 1
                             }
                    ]
                },
                {
                    _id: 20121004 
                    hits: 8
                    users: [ 
                             {
                                _id: 1,
                                hits: 2
                             }, 
                             {
                                _id: 2
                                hits: 3
                             },
                             {
                                _id: 3,
                                hits: 3
                             }
                    ]
                },
            ]
        },
        {
            _id: "pageViews"
            dailyStats: [
                {
                    _id: 20121005 
                    hits: 500
                    users: [ 
                             {
                                _id: 1, 
                                hits: 100
                             }, 
                             {
                                _id: 2
                                hits: 300
                             },
                             {
                                _id: 3,
                                hits: 100
                             }
                    ]
                },
                {
                    _id: 20121004
                    hits: 800
                    users: [ 
                             {
                                _id: 1, 
                                hits: 200
                             }, 
                             {
                                _id: 2
                                hits: 300
                             },
                             {
                                _id: 3,
                                hits: 300
                             }
                    ]
                },
            ]
        },
    ]
    

    我正在使用_id来保存event-id。 我正在使用dailyStats._id来保持它发生时(yyyyMMdd格式的整数)。 我正在使用dailySattes.users._id来表示用户的唯一ID哈希。

    为了获得唯一用户,我应该能够按照给定的日期范围(我将日期范围转换为yyyyMMdd)运行(mapreduce?)数组中项目的不同计数数量。

    我的问题:

    1. 这个数据模型对你有意义吗?我担心这个模型的可扩展性随着时间的推移(如果我在一些客户端有很多每日唯一访问者,它会导致一个巨大的文档)。 我想通过_id&lt;删除dailyStats文档[日期为yyyyMMdd]。通过这种方式,我可以将文档大小保持在一个合理的数字,但仍然存在限制。
    2. 是否有一种简单的方法可以运行“upsert”,如果尚未创建,还会创建dailyStats,添加用户(如果尚未创建)并为两者增加“hits”属性?
    3. map-reduce怎么样?你将如何处理它(需要在给定日期范围内的所有子文档的users._id上运行distinct)?使用新的聚合框架有更简单的方法吗?
    4. btw - 解决唯一身份访问者的另一个选择是使用Redis Bitmaps,但我不确定是否值得拥有多个数据存储(维护方面)。

1 个答案:

答案 0 :(得分:1)

对当前上述架构的评论很少。

我有点担心,因为你已经指出了可扩展性以及你真正在做多少预聚合。

我在做指标时曾经使用过的大多数Mongo实例都有类似于你所指出的情况,但你似乎真的非常依赖于对单个文档进行更新并且插入它的各个部分会变慢向下并可能导致一些锁定..

我可能会建议一条不同的路径,一个Mongo甚至在与他们谈论做指标时建议的路径。看到你已经有了一个你想要做的结构,我会创建一些类似的东西:

{
  "_id":"20121005_siteKey_page",
  "hits":512,
  "users":[
   {
     "uid":5, 
     "hits":512,
   }
}

通过这种方式,您可以将文档大小限制为快速插入的合理内容。从这里,您可以批量执行mapreduce工作,以进一步扩展您希望看到的内容。

这还取决于您的最终目标,您是否希望提供实时指标?你准备得到什么样的粒度? Redis地图可能是您想要至少看到的东西:精彩文章here

无论如何解决它都是一个有趣的问题:)

希望这有帮助!

相关问题