MapReduce в MongoDb

MapReduce - это обычная группировка, не больше не меньше. Сначала надо выбрать ключ, по которому производится группировка. Ну а потом придумать, как обрабатывать получившиеся значения и что возвращать методом Reduce. В mongoDB все это дело пишется на серверном Javascript.

Функция map должна вызывать функцию emit, которая принимает пару ключ значение. Ключ - это поле, по которому осуществяется группировка. Значения - это значение, которое попадет в функцию reduce.

След. функция reduce, принимает key и vals. Vals - это всегда коллекция, т.к туда пишутся результаты прошлых вызовов выборок. Пример функции reduce

function(key, values) {
    var result = {count: 0, likes: 0};

    values.forEach(function(value) {
      result.count += value.count;
      result.likes += value.likes;
    });

    return result;
  }


Есть еще функция function finalize(key, value) -> final_value она будет вызвана после того, как по ключу не будет больше вызываться функции reduce. Это можно использовать, чтоб завершить какие-то финальные дейсвтия. Т.к мы не знаем в функции reduce вызываемся мы последний раз или нет.


Также нужно указать параметр out. Фактически - это куда будет литься результирующая коллекция.

{ replace : "collectionName" } - значение по умолчанию, замена существующей коллекции.


Вот в этом куске кода, над коллекцией payments мы делаем mapReduce, в качестве ключа мы используем payment_time, который сокращен до точности часа. Этот код позволит нам получить количество платежей по часам за весь период, в течении которого совершались платежи.

db.system.js.save({
    "_id" : "aggregatePayments",
    value: function () {
     db.payments.mapReduce(
             // функция map
             function() {
                 var k = clone(this.payment_time);
                 k.setMinutes(0);
                 k.setSeconds(0);
                 k.setMilliseconds(0);
                 emit(k, this.amount);
             }, 
             // функция reduce
             function (key, vals) {
                 var total = 0;
                 for (var i = 0; i < vals.length; i++) {
                     total += vals[i];
                 }
                 return total;
             },
             {
              out : {merge : "chargebackByDay" }
             }
     );
    }
};


На выходе данные запишутся в коллекцию, где в качестве ключей будет использовано точное время, которое мы сократили до часа в функции map, а в качестве значения каждого ключа число total, которое было вычеслено для каждого ключа отдельно на шаге reduce.

Комментариев нет:

Отправить комментарий