подходит ли map / lower для нахождения медианы и режима набора значений для многих записей? - PullRequest
1 голос
/ 03 января 2012

У меня есть набор объектов в Mongodb, в каждый из которых встроен набор значений, например:

[1.22, 12.87, 1.24, 1.24, 9.87, 1.24, 87.65] // ... up to about 150 values

Является ли карта / уменьшение лучшим решением для нахождения медианы (среднего значения) и режима (наиболее распространенного значения) во встроенных массивах? Причина, по которой я спрашиваю, состоит в том, что и карта, и редукция должны возвращать одинаковый (структурно) набор значений. Похоже, что в моем случае я хочу взять набор значений (массив) и вернуть набор из двух значений (медиана, режим).

Если нет, как лучше к этому подойти? Я хочу, чтобы он выполнялся в граблях, если это актуально. Это было бы за одну ночь.

Ответы [ 3 ]

0 голосов
/ 03 января 2012

Я предполагаю, что вы хотите найти режим и медиану каждого документа, вы можете сделать это с помощью функции уменьшения карты.В этом случае вы вычисляете медиану и режим в функции карты, а уменьшение вернет результат карты нетронутым

map = function() {
   var res = 0;
   for (i = 0; i < this.marks.length; i++) {
      res = res + this.marks[i];
   }
   var median = res/this.marks.length;
   emit(this._id,{marks:this.marks,median:median});
}


reduce = function (k, values) {
    values.forEach(function(value) {
      result = value;
    });
    return result;
}

, а для этой коллекции

{ "_id" : ObjectId("4f02be1f1ae045175f0eb9f1"), "name" : "ram", "marks" : [ 1.22, 12.87, 1.24, 1.24, 9.87, 1.24, 87.65 ] }
{ "_id" : ObjectId("4f02be371ae045175f0eb9f2"), "name" : "sam", "marks" : [ 1.32, 11.87, 12.4, 4.24, 9.37, 3.24, 7.65 ] }
{ "_id" : ObjectId("4f02be4c1ae045175f0eb9f3"), "name" : "pam", "marks" : [ 3.32, 10.17, 11.4, 2.24, 2.37, 3.24, 30.65 ] }

вы можете получить медиану

  db.test.mapReduce(map,reduce,{out: { inline : 1}})

{
    "results" : [
        {
            "_id" : ObjectId("4f02be1f1ae045175f0eb9f1"),
            "value" : {
                "marks" : [
                    1.22,
                    12.87,
                    1.24,
                    1.24,
                    9.87,
                    1.24,
                    87.65
                ],
                "median" : 16.475714285714286
            }
        },
        {
            "_id" : ObjectId("4f02be371ae045175f0eb9f2"),
            "value" : {
                "marks" : [
                    1.32,
                    11.87,
                    12.4,
                    4.24,
                    9.37,
                    3.24,
                    7.65
                ],
                "median" : 7.155714285714285
            }
        },
        {
            "_id" : ObjectId("4f02be4c1ae045175f0eb9f3"),
            "value" : {
                "marks" : [
                    3.32,
                    10.17,
                    11.4,
                    2.24,
                    2.37,
                    3.24,
                    30.65
                ],
                "median" : 9.055714285714286
            }
        }
    ],
    "timeMillis" : 1,
    "counts" : {
        "input" : 3,
        "emit" : 3,
        "reduce" : 0,
        "output" : 3
    },
    "ok" : 1,
}
0 голосов
/ 09 февраля 2012

Я бы начал читать это http://www.mongovue.com/2010/11/03/yet-another-mongodb-map-reduce-tutorial/.

Я думаю, что вы хотите

  1. Этап карты для генерации вашего ключа и отдельного элемента данных,
  2. Стадия редукции для размещения всех элементов данных в массив данных для каждого ключа,
  3. Стадия завершения для выполнения вашего среднего, среднего и режима операции над всей коллекцией.


Завершить функцию

Функция завершения может быть запущена после сокращения. Такая функция не является обязательной и не является необходимой для многих карт / уменьшить случаев. Функция finalize принимает ключ и значение и возвращает окончательное значение.

function finalize(key, value) -> final_value

Ваша функция уменьшения может быть вызванным несколько раз для одного и того же объекта . Используйте финализировать, когда что-то должно быть сделано только один раз в конце; например расчет среднего.

Взято из http://www.mongodb.org/display/DOCS/MapReduce

0 голосов
/ 03 января 2012

Здесь есть ключевой вопрос относительно ожидаемого результата.Это не на 100% ясно из вашего вопроса, какой вы хотите.

Вы хотите (A) :

{ _id: "document1", value: { mode: 1.0, median: 10.0 } }
{ _id: "document2", value: { mode: 5.0, median: 150.0 } }
... one for each document

... или хотите (B) , режим и медиана для всех комбинаций всех массивов.

  • Если ответ (A) , то Map / Reduce будет работать .
  • Если ответ (B) , то Map / Reduce , вероятно, не будет работать .

Если вы планируете сделать (A) , пожалуйста, внимательно прочитайте документацию по M / R и поймите ограничения.Хотя опция (A) может быть картой / уменьшением, она также может быть просто большим циклом for с upsert в коллекции «summary» или даже обратно воригинальная коллекция.Это может быть даже более эффективным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...