2010-10-07 131 views
4

我有一个M/R函数,并且我将NaN作为一些结果的值。我没有任何JS经验。使用Java驱动程序转义JS。MapReduce返回NaN

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} 

非常感谢。

回答

1

只考虑JS的一部分,我不知道下面的部分是否有效 -

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

,而不是尝试这个 -

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

希望帮助!

+0

该部分是有效的,因为我会得到一些减少操作的正确结果,并为其他人的NaN。 – theTuxRacer 2010-10-07 07:59:34

+0

我只质疑该部分的句法有效性。我可以很好地理解它意味着什么! – anirvan 2010-10-07 08:21:07

2

我解决了它。 anirvan说,改变了循环。但我仍然得到了NaN。所以我改变了这样的返回声明:

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

这样做的伎俩。我需要额外的一行来解析它,但需要IDC。

9

我看你已经解决了这个问题,但是这里的为什么会出现这个问题。

MongoDB可能会重新运行您的reduce函数对以前的reduce通道的结果。这被称为重新减少

如果再降低发生在你原来的情况下,你可能最终会以这样的价值观:

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

所有{ count: 1 }值由你的地图功能发出的。数字43是以前的减少呼叫的结果。然后,您减少功能将访问count财产的数个:

count += 4["count"]; 

一些不具有count属性,所以它会返回undefined。将undefined添加到数字将导致NaN

为了避免这种难以调试的问题,您需要确保您的reduce函数是幂等的。最简单的方法就是返回你发出的;您在reduce函数中返回的值应该与在地图函数中发出的值格式相同。

+1

非常感谢,我多次阅读,但是当你这样解释时,我理解得很好。 – theTuxRacer 2010-10-07 08:15:22