如何映射/减少两个MongoDB集合

时间:2011-10-21 21:57:18

标签: mongodb mongoid mapreduce

我是map / reduce的新手,并试图找出一种方法来使用map / reduce来收集以下数据,而不是使用我的(慢)应用程序逻辑:

我有一个'项目'集合,与集合'tasks'有1:n的关系。现在,我希望收到一系列结果,这些结果为我提供项目名称,其中第一个是具有最多任务的项目,最后一个项目具有最少的任务。

甚至更好的一系列哈希值也告诉我每个项目有多少任务(假设项目名称是唯一的:

[project_1: 23, project_2: 42, project_3: 82]

对于地图,我尝试了类似的内容:

map = function () {
  emit(this.project_id, { count:1 });
}

并减少:

reduce = function (key, values) {
  var sum = 0;
  values.forEach(function(doc){ sum += 1; });
  return { count:sum };
}

我针对我的任务集合解决了这个问题:

var mr = db.tasks.mapReduce(map, reduce, { out: "results" });

但在查询时我得到了至关重要的结果:

db[mr.result].find();

我在Rails上使用Mongoid并完全迷失了它。有人能指出我正确的方向吗?

提前谢谢。 菲利克斯

1 个答案:

答案 0 :(得分:2)

看起来一般,但我发现至少有一个问题:reduce函数中的求和步骤应为

  values.forEach(function(doc){ sum += doc.count ; });

因为该函数可能正在减少本身是先前减少步骤的乘积的值,并且因此具有计数值> 1。

这是一个常见的疏忽,在这里提到:http://www.mongodb.org/display/DOCS/Troubleshooting+MapReduce

希望有所帮助!