MongoDB映射/减少多个集合?

时间:2010-10-01 08:01:11

标签: mongodb mapreduce

首先,背景。我曾经有一个集合logs并使用map / reduce来生成各种报告。大多数这些报告都是基于一天内的数据,所以我总是有条件d: SOME_DATE。当logs集合变得非常大时,插入变得极其缓慢(比我们监视的应用程序生成日志的速度慢),即使在丢弃大量索引之后也是如此。因此我们决定将每一天的数据放在一个单独的集合中 - logs_YYYY-mm-dd - 这样索引就更小了,我们甚至不需要索引日期。这很酷,因为大多数报告(因此map / reduce)都是每日数据。但是,我们有一份报告,我们需要覆盖多天。

现在问题。有没有办法在多个集合上运行map / reduce(或更确切地说,地图),就好像它只是一个?

2 个答案:

答案 0 :(得分:35)

可以使用键和所有对应值调用一次reduce函数(但仅当键有多个值时 - 如果只有1个值,则根本不会调用它关键)。

也可以多次调用它,每次都使用一个键,只有相应值的子集,以及之前的该键的减少结果。此方案称为重新减少。为了支持重新缩减,您的reduce函数应为idempotent

幂等减少函数有两个关键特性:

  • reduce函数的返回值应该与格式相同。所以,如果你的reduce函数接受一个字符串数组,函数应该返回一个字符串。如果它接受具有多个属性的对象,则应返回包含这些属性的对象。这可以确保在使用先前reduce的结果调用函数时函数不会中断。
  • 不要根据值的数量进行假设。不能保证values参数包含 all 的值给定的密​​钥。因此,在计算中使用values.length是非常危险的,应该避免使用。

更新:最新的MongoDB版本不需要以下两个步骤(甚至可能,我还没有检查过)。如果您在map-reduce options中指定输出集合,它现在可以为您处理这些步骤:

{ out: { reduce: "tempResult" } }

如果你的reduce函数是幂等的,你应该没有任何问题地图减少多个集合。只需重新减少每个集合的结果:

第1步

对每个必需的集合运行map-reduce,并将结果保存在单个临时集合中。您可以使用finalize function

存储结果
finalize = function (key, value) {
  db.tempResult.save({ _id: key, value: value });
}

db.someCollection.mapReduce(map, reduce, { finalize: finalize })
db.anotherCollection.mapReduce(map, reduce, { finalize: finalize })

第2步

在临时集合上运行另一个map-reduce,使用相同的reduce函数。 map函数是一个简单的函数,用于从临时集合中选择键和值:

map = function () {
  emit(this._id, this.value);
}

db.tempResult.mapReduce(map, reduce)

这第二个map-reduce基本上是一个重新缩减,应该可以为你提供所需的结果。

答案 1 :(得分:1)

我使用了map-reduce方法。这是一个例子。

var mapemployee = function () {
    emit(this.jobid,this.Name);};

var mapdesignation = function () {
    emit(this.jobid, this.Designation);};

var reduceF = function(key, values) {
    var outs = {Name:null,Designation: null};
    values.forEach(function(v){
    if(outs.Name ==null){
   outs.Name = v.Name }
   if(outs.Name ==null){
    outs.Nesignation = v.Designation}                    
     });
    return outs;
};

result = db.employee.mapReduce(mapemployee, reduceF, {out: {reduce: 'output'}});
result = db.designation.mapReduce(mapdesignation,reduceF, {out: {reduce: 'output'}});

参考:http://www.itgo.me/a/x3559868501286872152/mongodb-join-two-collections