0

我试图找出一种使用 MongoDB 和 Map/Reduce 按人口统计对用户站点访问进行分组的好方法。我有以下收藏:

实地考察 - 示例:

{
    userId: '184792',
    resource: '/example/foo',
    visitTime: ISODate(...)
}

用户配置文件 - 示例:

{
    userId: '184792',
    demo: '18-30',
    city: 'Austin',
    state: 'TX',
    ...
}

我想生成一份报告,显示每天或每月按人口统计的网站访问次数。但是,如果我对站点访问进行 Map/Reduce,我只能访问 userId,而不是人口统计信息,因此我无法根据人口统计信息发出密钥。事实上,如果我想按任何用户属性(例如 State)进行分组,那也是不可能的。

有谁知道在 MongoDB 中解决这个问题的最佳实践方法是什么?我应该复制每个站点访问文档中的所有用户属性吗?我应该在应用程序代码中进行某种类型的重新减少,我可以在其中使用多个查询加入集合吗?还是我只是使用错误的工具来解决此类问题?

感谢您的任何建议。

4

2 回答 2

0

这里有三个解决方案:

  1. 将人口统计数据非规范化到站点访问中。
  2. 做一个“客户端”的 Map/Reduce。即:编写一个循环访问访问的脚本,加载适当的用户配置文件,然后更新摘要集合。
  3. 为此保留实时计数器。

有谁知道在 MongoDB 中解决这个问题的最佳实践方法是什么?

对于 MongoDB,答案通常是“取决于”。在这种情况下,确实如此。

需要考虑的一些问题:

  • 您是否已经在每次访问时查找个人资料数据?
  • 您想要“实时”数据吗?
  • 您是否提前知道所有预期的汇总?
  • 您想存储所有交易数据还是只关心汇总?

通常,这里的解决方案是#1 和#3 的组合。

如果您想要交易数据和“灵活”的报告,那么您需要在每次访问时保留配置文件数据。

如果您提前知道您的主要报告,那么我建议使用某种形式的计数器并在您编写交易的同时写入这些。因此,您基本上可以即时构建您的报告数据集。是的,它的写入次数更多,但 MongoDB 更喜欢这种进行大量写入的模式。

于 2012-06-07T19:29:41.933 回答
0

实际上,您可以使用reduceoutput 选项将两个 map reduce 结果合并在一起。

{ reduce : "collectionName" } - 如果结果集中和旧集合中的给定键存在文档,则将对这两个值执行归约操作(使用指定的归约函数)并将结果写入输出集合。如果提供了 finalize 函数,这也将在 reduce 之后运行。

您需要将两个集合映射到一种通用格式,以便您可以对每个源映射文档中的一个文档执行此缩减步骤,并合并每个集合中的相应字段。

有关示例,请参阅此博客条目。

于 2012-06-07T19:41:48.293 回答