MongoDB MapReduce计算Delta

时间:2014-11-18 09:51:31

标签: mongodb mapreduce

早上好,我正在调查使用MongoDB MapReduce函数。

我的数据集看起来像这样

[{
     "Name" : "Person 1",
    "RunningSpeed" : [{
            "Date" : ISODate("2005-07-23T23:00:00.000Z"),
            "Value" : 10
        }, {
            "Date" : ISODate("2006-07-23T23:00:00.000Z"),
            "Value" : 20
        }, {
            "Date" : ISODate("2007-07-23T23:00:00.000Z"),
            "Value" : 30
        }, {
            "Date" : ISODate("2008-07-23T23:00:00.000Z"),
            "Value" : 40
        }

    ]

}, {
    "Name" : "Person 2",
    "RunningSpeed" : [{
            "Date" : ISODate("2005-07-23T23:00:00.000Z"),
            "Value" : 5
        }, {
            "Date" : ISODate("2006-07-23T23:00:00.000Z"),
            "Value" : 10
        }, {
            "Date" : ISODate("2007-07-23T23:00:00.000Z"),
            "Value" : 20
        }, {
            "Date" : ISODate("2008-07-23T23:00:00.000Z"),
            "Value" : 40
        }

    ]

}, {
    "Name" : "Person 3",
    "RunningSpeed" : [{
            "Date" : ISODate("2005-07-23T23:00:00.000Z"),
            "Value" : 20
        }, {
            "Date" : ISODate("2006-07-23T23:00:00.000Z"),
            "Value" : 10
        }, {
            "Date" : ISODate("2007-07-23T23:00:00.000Z"),
            "Value" : 30
        }, {
            "Date" : ISODate("2008-07-23T23:00:00.000Z"),
            "Value" : 25
        }

    ]

}
]

我想计算每年的增量(或变化)。

我的地图功能是

function map() {
   this.RunningSpeed.forEach(function(data){
      var year = data.Date.getFullYear();
      emit(year, // Or put a GROUP BY key here, the group by key is Date.getFullYear()
          {sum: data.Value, // the field you want stats for
           min: data.Value,
           max: data.Value,
           count: 1,

          });
   });
}

我的reduce函数只返回当前年份的delta,这可以理解为该集合按年份分组。

reduce : function reduce(key, values) {
var a = values[0]; // will reduce into here
  for (var i=1/*!*/; i < values.length; i++){
      var b = values[i]; // will merge 'b' into 'a'


    // temp helpers
    var delta = a.sum - b.sum; // a.mean - b.mean


    // do the reducing
    a.diff = delta;

}

return a; 
}

那么我又如何调整以前的函数来生成从前一年计算的每年的增量?

1 个答案:

答案 0 :(得分:0)

根据你的评论和我的建议,这个m / r给你们两个。请阅读评论以获得澄清。

db.runners.mapReduce(

  // Map
  function(){
    for(var i =0; i < this.RunningSpeed.length; i++){
      var value={
        date: this.RunningSpeed[i].Date,
        speed: this.RunningSpeed[i].Value};

      // We emit all in single key value pairs
      emit(this.Name,value);
    }
  },

  // Reduce
  function(key,values){

    //In the beginning, delta is null
    var delta=0;

    // And we start to compare with the first value
    var last=values[0].speed;

    for(var idx=1; idx < values.length; idx++){

      // The absolute delta (all changed over all years)
      delta += Math.abs( values[idx].speed - last );

      // I think here was your problem.
      // You needed to save "last" years value for comparison with the current value.
      last=values[idx].speed;
    }

    var reduced = {

      // The relative delta (speed gain and loss over all years)
      delta_rel:values[values.length-1].speed - values[0].speed,

      delta_abs:delta
    };

    return reduced;

  },
  // Options
  {
     // Output collection
     out:"runner_test",
     // Sort order of the initial documents
     sort:{"RunningSpeed.Date":1}}
)