mongodb - 如何对另一个集合中的键进行 mapreduce

标签 mongodb mapreduce

假设我有一组这样的用户:-

{
  "_id" : "1234",
  "Name" : "John",
  "OS" : "5.1",
  "Groups" : [{
      "_id" : "A",
      "Name" : "Group A"
    }, {
      "_id" : "C",
      "Name" : "Group C"
    }]
}

我收集了这样的事件:-

{
  "_id" : "15342",
  "Event" : "VIEW",
  "UserId" : "1234"
}

我可以使用 mapreduce 来计算每个用户的事件数,因为我可以发出“UserId”并计算它,但是我现在想做的是按组计算事件数。

如果我的事件文档中有一个“Groups”数组,那么这会很容易,但我没有,这只是一个例子,实际应用要复杂得多,我不想复制所有这些数据都放入事件文档中。

我在 http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/ 看到了一个例子但我看不出这在这种情况下如何应用,因为它是从两个地方聚合值...我真正想做的就是执行查找。

在 SQL 中,我会简单地将扁平化的 UserGroup 表连接到事件表,然后 GROUP BY UserGroup.GroupName

我对 mapreduce 的多次传递感到满意...首先通过 UserId 计数为 { "_id": "1234", "count": 9 } 但我在下一次传递时卡住了...如何包含群组ID

我考虑过的一些潜在方法:-

  • 在事件文档中包含团体信息(不可行)
  • 弄清楚如何“加入”用户集合或从 map 函数中查找用户组,这样我也可以发出组 ID(不知道该怎么做)
  • 找出如何将事件和用户集合“加入”到我可以运行 mapreduce 的第三个集合中

每种方法有哪些可能性以及有哪些好处/问题?

最佳答案

第三种方法是要走的路:

Work out how to "join" the event and user collections into a third collection I can run mapreduce over

为此,您需要使用 map-reduce 所需的“联合”数据创建一个新集合 J。为此,您可以使用多种策略:

  1. 更新您的应用程序以在正常业务过程中插入/更新 J。这在您需要非常频繁地运行 MR 并使用最新数据的情况下是最好的。它会大大增加代码的复杂性。从实现的角度来看,您可以直接(通过写入 J)或间接(通过将更改写入日志集合 L,然后应用"new"更改)来执行此操作到 J)。如果您选择日志收集方法,您将需要一个策略来确定发生了什么变化。有两个常见的:高水位线(基于 _id 或时间戳)和使用日志收集作为队列与 findAndModify命令。

  2. 以批处理模式创建/更新J。在高性能系统的情况下,上述策略的多次更新会影响性能,这是可行的方法。如果您不需要非常频繁地运行 MR 和/或您不必保证最新的数据准确性,这也是可行的方法。

如果您选择 (2),您将不得不遍历您需要加入的集合中的文档——如您所知,Mongo map-reduce 在这里帮不了您。有许多可能的方法可以做到这一点:

  1. 如果您没有很多文档并且它们很小,您可以通过直接连接到数据库在数据库外部进行迭代。

  2. 如果您不能执行 (1),您可以使用 db.eval() 在 DB 内部迭代。如果文档数量不小,请确保使用 nolock: true 因为 db.eval 默认是阻塞的。这通常是我选择的策略,因为我倾向于处理非常大的文档集,而且我负担不起通过网络移动它们的费用。

  3. 如果您不能执行 (1) 并且不想执行 (2),您可以使用临时数据库将集合克隆到另一个节点。 Mongo有一个方便的cloneCollection为此命令。请注意,如果数据库需要身份验证,这将不起作用(不要问为什么;这是一个奇怪的 10gen 设计选择)。在这种情况下,您可以使用 mongodumpmongorestore。一旦您拥有新数据库的本地数据,您就可以根据需要参与其中。完成 MR 后,您可以更新生产数据库中的结果集合。我将此策略用于具有大量预处理的一次性 map-reduce 操作,以免加载生产副本集。

祝你好运!

关于mongodb - 如何对另一个集合中的键进行 mapreduce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12025053/

相关文章:

hadoop - 抑制命令行输出 hadoop fs 命令

mongodb - 我的 mongoexport 的 json 格式不断出现错误

hadoop - 使用hadoop执行jar文件

java - 在hadoop中计算 'n'最大值

mongodb - 如何在 MongoDB C# 驱动程序中使用 SafeMode

hadoop - 使用 Hadoop mapreduce 进行并行缩减

hadoop - 输入拆分的数量等于映射器的数量?

javascript - mongodb/nodejs : using variables in $inc doesn't work

javascript - 从 node.js 的 mongodb 集合中删除文档

Mongodb SaaS 单数据库与多数据库