Как использовать переменные в MongoDB Map-уменьшить функцию карты - PullRequest
19 голосов
/ 01 сентября 2011

При наличии документа

{_id:110000, groupings:{A:'AV',B:'BV',C:'CV',D:'DV'},coin:{old:10,new:12}}

Мои спецификации требуют спецификации атрибутов для отображения и агрегирования во время выполнения, поскольку интересующие пользователя группы не известны заранее, но определяются пользователемво время выполнения.

Например, один пользователь будет указывать [A, B], что приведет к выбросам при отображении

emit( {A:this.groupings.A,B:this.groupings.B},this.coin )

, тогда как другой захочет указать [A, C], что приведет квыбросы при отображении

emit( {A:this.groupings.A,C:this.groupings.C},this.coin )

B / c функции картографирования и редуктора выполняют на стороне сервера и не имеют доступа к клиентским переменным, я не смог придумать способ использования переменнойключ карты в функции картографирования.

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

Прежде чем я начну пытаться динамически построить сценарий Java для выполнениячерез драйвер, у кого-нибудь есть лучшее предложение?Может быть, функция 'group' лучше справится с этим сценарием?

Ответы [ 2 ]

40 голосов
/ 12 июля 2012

Как указал @Dave Griffith, вы можете использовать параметр scope функции mapReduce.

Я изо всех сил пытался выяснить, как правильно передать его в функцию, потому что, как отмечали другие, документация не очень подробная. Наконец, я понял, что mapReduce ожидает 3 параметра:

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

В конце концов я получил следующий код в Javascript:

// I define a variable external to my map and to my reduce functions
var KEYS = {STATS: "stats"};

function m() {
    // I use my global variable inside the map function
    emit(KEYS.STATS, 1);
}

function r(key, values) {
    // I use a helper function
    return sumValues(values);
}

// Helper function in the global scope
function sumValues(values) {
    var result = 0;
    values.forEach(function(value) {
        result += value;
    });
    return result;
}

db.something.mapReduce(
    m,
    r,
    {
         out: {inline: 1},
         // I use the scope param to pass in my variables and functions
         scope: {
             KEYS: KEYS,
             sumValues: sumValues // of course, you can pass function objects too
         }
    }
);
17 голосов
/ 01 сентября 2011

Вы можете передавать глобальные данные только для чтения в функции преобразования карт, используя параметр "scope" в команде map-проводить.Боюсь, это не очень хорошо задокументировано.

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