MongoDB: Mapreduce: уменьшить-> несколько еще не поддерживается - PullRequest
14 голосов
/ 18 ноября 2011

У меня есть коллекция MongoDB (названная «каталог»), содержащая около 5 астрономических каталогов.Некоторые из этих каталогов ссылаются друг на друга, поэтому один из документов может выглядеть примерно так:

{ "_id" : ObjectId("4ec574a68e4e7a519166015f"), "bii" : 20.9519, "class" : 2480, "cpdname" : "CPD -21 6109", "decdeg" : -21.8417, "decpm" : 0.004, "dmname" : "-21 4299", "hdname" : "HD 145612", "lii" : 352.8556, "name" : "PPM 265262", "ppmname" : "PPM 265262", "radeg" : 243.2005, "rapm" : 0.0012, "vmag" : 9.6, "xref" : [ ] }

Что я хочу сделать, это использовать mapreduce для перемещения полей, таких как "hdname", "ppmname"и т. д. в массив внешних ссылок (затем сбросьте их).

Поэтому я пытаюсь сделать это по одному, начиная с поля hdname.Вот карта и функции сокращения:

map = function() {
    for (var hdname in this.hdname) {
        emit(this._id,this.hdname);
    }
}


reduce = function(key, values) {
    var result = [];
    for (var hdname in values) {
        result.push(hdname);
    }
    return result;
}

Я пытаюсь выполнить следующую команду в оболочке mongo:

db.catalog.mapReduce(map, reduce,"catalog2");

К сожалению, я получаю следующую ошибку:

Thu Nov 17 15:52:17 uncaught exception: map reduce failed:{
    "assertion" : "reduce -> multiple not supported yet",
    "assertionCode" : 10075,
    "errmsg" : "db assertion failure",
    "ok" : 0
}

Очевидно, что я новичок ... кто-нибудь может помочь?

Джейсон

Ответы [ 3 ]

30 голосов
/ 18 ноября 2011

Документация гласит "В настоящее время возвращаемое значение из функции сокращения не может быть массивом (обычно это объект или число)."

Так что вместо этого создайте объект и включите в него ваш массив. Также убедитесь, что выходные данные в поле Reduce совпадают с типом ввода, поэтому вам нужно будет выдать аналогичное значение в операции карты.

НО ... зачем использовать Map-Reduce для этого? Если вы передадите значение _id, уменьшать нечего, так как каждый ключ будет уникальным. Почему бы просто не выполнить итерацию по коллекции, копируя значения и обновляя каждую запись одну за другой?

2 голосов
/ 22 января 2014

Мне недавно нужно было также вернуть словарь в моем шаге сокращения. Решил это, сделав

return values.toString();

в моем коде редуктора. После этого мне нужно разобрать результат, чтобы найти людей, но это не имело большого значения ...

0 голосов
/ 31 января 2018

попытаться вернуть объект в функцию уменьшения

reduce = function(key, values) {
   var result = [];
   for (var hdname in values) {
     result.push(hdname);
   }
   return {value:result};
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...