MapReduce возвращает NaN - PullRequest
       6

MapReduce возвращает NaN

4 голосов
/ 07 октября 2010

У меня есть функция M / R, и я получаю NaN в качестве значения для некоторых результатов.У меня нет опыта работы с JS.Я спасаюсь от JS с помощью драйверов Java.

String map = "function(){" + " emit({"
            + "country: this.info.location.country, "
            + "industry: this.info.industry}, {count : 1});  }";

String reduce = "function(key, values){var count = 0.0;"
            + "values.forEach(function(v){ count += v['count'];});"
            + "return count;}";
MapReduceOutput output = collection.mapReduce(map, reduce, null,
            new BasicDBObject("lid", "foo"));

Пример, помогающий прояснить ситуацию:

{"_id":{"country":"gb", "industry":"foo"}, "value":NaN}

Большое спасибо.

Ответы [ 3 ]

9 голосов
/ 07 октября 2010

Я вижу, что вы решили проблему, но вот почему возникла проблема.

MongoDB может повторно выполнить вашу функцию уменьшения по результатам предыдущих проходов уменьшения.Это называется повторное уменьшение .

Если повторное уменьшение произошло в исходном сценарии, вы можете получить такие значения:

[
  { count: 1 },
  { count: 1 },
  4
  { count: 1 },
  { count: 1 },
  { count: 1 },
  3
  { count: 1 },
]

Все{ count: 1 } значения выдаются вашей функцией карты.Числа 4 и 3 являются результатами предыдущих сокращенных вызовов.Ваша функция сокращения затем получит доступ к свойству count числа:

count += 4["count"];

Число не имеет свойства count, поэтому оно вернет undefined.Добавление undefined к числу приведет к NaN.

Чтобы избежать такой сложной для отладки проблемы, вам нужно убедиться, что ваша функция сокращения идемпотентна.Самый простой способ сделать это - вернуть то, что вы излучаете ;значение, которое вы возвращаете в функции сокращения, должно иметь тот же формат, что и значения, которые вы выводите в функции карты.

2 голосов
/ 07 октября 2010

Я решил это. Изменил цикл, как сказал анирван. Но все же я получил NaN. Так что я изменил оператор возврата как таковой:

for(var i in values) { count += values[i].count; } return {count: count}; }

Это добилось цели. Мне понадобится дополнительная строка для разбора, но IDC.

1 голос
/ 07 октября 2010

Учитывая только часть JS, я не уверен, что следующая часть действительна -

values.forEach(function(v){ count += v['count'];});

попробуйте вместо этого -

var v;
for (v in values)
{
    ....
}

надеюсь, это поможет!

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