MapReduce返回NaN

时间:2010-10-07 06:44:02

标签: java javascript mongodb mapreduce

我有一个M / R功能,我将NaN作为某些结果的值。我没有任何JS经验。我使用Java驱动程序逃避JS。

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"));

示例ti帮助清除事物:

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

非常感谢。

3 个答案:

答案 0 :(得分:9)

我看到你已经解决了这个问题,但是为什么发生了问题。

MongoDB可能会在之前的reduce传递结果上重新运行reduce函数。这称为 re-reduce

如果原始方案中发生了重新缩减,您最终可能会得到如下值:

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

地图功能会发出所有{ count: 1 }值。数字43是之前减少调用的结果。然后,您的reduce函数将访问数字的count属性:

count += 4["count"];

数字没有count属性,因此会返回undefined。将undefined添加到某个数字会产生NaN

为了避免这种难以调试的问题,您需要确保reduce函数是幂等的。实现此目的的最简单方法是返回您发出的内容;您在reduce函数中返回的值应与您在map函数中发出的值具有相同的格式。

答案 1 :(得分:2)

我解决了。改变了循环,正如anirvan所说。但我仍然有一个NaN。所以我改变了返回语句:

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

这就是诀窍。我需要额外的一行来解析它,但IDC。

答案 2 :(得分:1)

仅考虑JS部分,我不确定以下部分是否有效 -

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

试试这个 -

var v;
for (v in values)
{
    ....
}
希望有所帮助!