MongoDB地图减少:"first/lowest"值?



我有这样的文档:

{
        "_id" : "someid",
        "name" : "somename",
        "action" : "do something",
        "date" : ISODate("2011-08-19T09:00:00Z")
}

我想把它们映射成这样:

{
        "_id" : "someid",
        "value" : {
            "count" : 100,
            "name" : "somename",
            "action" : "do something",
            "date" : ISODate("2011-08-19T09:00:00Z")
            "firstEncounteredDate" : ISODate("2011-07-01T08:00:00Z")
        }
}

我想按"名称"、"动作"one_answers"日期"对地图简化文档进行分组。但是每个文档都应该有这个"firstEncounteredDate",它包含最早的"日期"(实际上是按"名称"one_answers"动作"分组的)。

如果我按名称,操作和日期分组,firststencountereddate将始终是日期,这就是为什么我想知道是否有任何方法在执行map-reduce时获得"最早日期"(按"名称"one_answers"操作"分组)。

如何在mapreduce中做到这一点?

编辑:更多关于firstEncounteredDate的细节(来自@beny23)

似乎两次map-reduce符合要求,有点类似于这个例子:http://cookbook.mongodb.org/patterns/unique_items_map_reduce/

在步骤#1中,将原始的"name"x"action"x"date"文档仅按"name"one_answers"action"分组,在reduce期间将各种"date"值收集到"dates"数组中。使用'finalize'函数查找所收集日期的最小值。

未测试的代码:

// phase i map function : 
function () {
  emit( { "name": this.name, "action": this.action } , 
        { "count": 1, "dates": [ this.date ] } );
}
// phase i reduce function : 
function( key, values ) {
  var result = { count: 0, dates: [ ] };
  values.forEach( function( value ) {
    result.count += value.count;
    result.dates = result.dates.concat( value.dates );
  }
  return result;
}
// phase i finalize function : 
function( key, reduced_value ) {
  var earliest = new Date( Math.min.apply( Math, reduced_value.dates ) );
  reduced_value.firstEncounteredDate = earliest ;
  return reduced_value;
}

在步骤#2中,使用步骤#1中生成的文档作为输入。对于每个"name"x"action"文档,为每个收集到的日期生成一个新的"name"x"action"x"date"文档,以及现在确定的"name"x"action"对共有的最小日期。按"名称"x"动作"x"日期"分组,汇总reduce过程中每个单独日期的计数。

同样未经测试的代码:

// phase ii map function : 
function() {
  this.dates.forEach( function( d ) {
    emit( { "name": this.name, "action": this.action, "date" : d } ,
          { "count": 1, "firstEncounteredDate" : this.firstEncounteredDate } );
  }
}
// phase ii reduce function : 
function( key, values ) {
  // note: value[i].firstEncounteredDate should all be identical, so ... 
  var result = { "count": 0, 
                 "firstEncounteredDate": values[0].firstEncounteredDate };
  values.forEach( function( value ) {
    result.count += value.count;
  }
  return result;
}

步骤#2显然没有做很多繁重的工作——它主要是复制每个文档N次,每个唯一日期一次。我们可以很容易地在pass #1的减少步骤中建立一个独特日期的发生率计数图。(事实上,如果我们这样做,那么在传递#1的值中使用"count"字段就没有真正的意义了。)但是执行第二遍是一种相当轻松的方法,可以生成包含所需文档的完整目标集合。

相关内容

  • 没有找到相关文章

最新更新