Как получить доступ к this._id в функции карты в MongoDB MapReduce? - PullRequest
0 голосов
/ 24 октября 2011

Я делаю MapReduce в Mongo, чтобы сгенерировать обратный индекс токенов для некоторых документов.У меня проблемы с доступом к _id документа в функции карты.

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

{
        "_id" : ObjectId("4ea42a2c6fe22bf01f000d2d"),
        "attributes" : {
                "name" : "JCDR 50W38C",
                "upi-tokens" : [
                        "50w38c",
                        "jcdr"
                ]
        },
        "sku" : "143669259486830515"
}

(Поле ttributes ['upi-tokens'] представляет собой список текстовых токенов, которые я хочу использоватьсоздать обратный индекс для.)

Функция карты (источник проблемы):

m = function () {
    this.attributes['upi-tokens'].forEach(
         function (token) { emit(token, {ids: [ this._id ]} ); }
    ); }

Функция уменьшения:

r = function (key, values) {
    var results = new Array;
    for (v in values) {
        results = results.concat(v.ids);
    }
    return {ids:results};
}

Вызов MapReduce:

db.offers.mapReduce(m, r, { out: "outcollection" } )

ПРОБЛЕМА Результирующая коллекция имеет ноль значений везде, где я ожидаю идентификатор вместо реальных строк ObjectID.

Возможная причина:

Я ожидал, что следующие 2 функции будут эквивалентны, но это не так.

m1 = function (d) { print(d['_id']); }
m2 = function () { print(this['_id']); }

Теперь я запускаю:

db.offers.find().forEach(m1)
db.offers.find().forEach(m2)

Разница в том, что m2 печатает undefined для каждого документа, а m1 печатает идентификаторы по желанию.Понятия не имею, почему.

Вопросы:

  1. Как получить _id текущего объекта в функции map для использования в MapReduce?this._id или this ['_ id'] не работает.
  2. Почему именно m1 и m2 не эквивалентны?

1 Ответ

3 голосов
/ 24 октября 2011

Приступил к работе ... Я сделал довольно простые ошибки JS:

  1. inner forEach () в функции map, кажется, перезаписывает объект this; это уже не основной документ (с _id), а повторяющийся объект внутри цикла) ...
  2. ... или это было просто потому, что в JS цикл for..in возвращает только ключи, а не значения, т.е.

    для (v в значениях) {

теперь требуется

values[v]

для доступа к фактическому значению массива. Duh ...

Способ, которым я обошел ошибку # 1 , заключается в использовании цикла for..in вместо цикла forEach () в функции карты:

m = function () {
            for (t in this.attributes['upi-tokens']) {
                var token = this.attributes['upi-tokens'][t];
                emit (token, { ids: [ this._id ] });
            }
        }

Таким образом, «это» относится к тому, что ему нужно.

Может также сделать:

that = this;
this.attributes['upi-tokens'].forEach( function (d) { 
...
that._id...
...
}

вероятно, будет работать просто отлично.

Надеюсь, это кому-нибудь поможет.

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