2010-10-07 134 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