2012-12-12 41 views
1

我應用地圖減少功能,但面臨一個問題。在一個記錄的情況下,它返回的ID,而不是數= 1地圖減少功能返回ID而不是計數

map_func = """function() { 
     emit(this.school_id, this.student_id); 
    }""" 
    reduce_func = """ 
     function (k, values) {    
       values.length; 
     } 
    """ 

如果學校100只有一個學生,那麼它應該返回學校編號100,值= 1,但在這種情況下它返回 schoolid = 100 ,值= 12(12是它在db中的學生ID)。對於其他記錄它工作正常。

 map_func = """function() {    
     emit({this.school_id, this.student_id},{count:1}); 
    }""" 
    reduce_func = """ 
     function (k, values) { 
      var count =0 ; 
      values.forEach(function(v) 
      { 
       count += v['count']; 
      }); 
      return {count:count}; 
     } 
    """ 
    map_func2 = """ 
    function() { 
     emit(this['_id']['school_id'], {count: 1}); 
    } 
    """ 

http://cookbook.mongodb.org/patterns/unique_items_map_reduce/ 我用這個例子,但它使用了兩張地圖,減少功能,所以花了更多的時間。

+0

你錯誤地發出了什麼。你必須發佈你想要的實際最終結果。學校100有1名學生,所以你必須發出1.減少是你添加所有不同的發射值的地方。 –

回答

2

看起來你可能會誤解mapReduce的一些機制。

發射將在每個文檔上被調用,但reduce只會在具有多個值的鍵上調用(因爲reduce函數的目的是將結果數組合併成一個)。

你映射函數是錯誤的 - 它需要發出一個鍵,然後是你想要的值 - 在這種情況下是一個計數。

您的reduce函數需要減少這些計數(添加它們),但即使被多次調用(重新減少以前減少的結果),它也必須正常工作。

我推薦閱讀here瞭解更多詳情。

+0

問題是在count = 1的情況下,它沒有進入reduce函數。 – user493550

+0

它不需要進入減少功能 - 減少是結合來自地圖功能的多個結果。我認爲你需要回顧一些它如何工作的例子。你的減少應該是從數組中獲得的所有計數加到當前運行計數。 –

0

,如果你想計算每所學校學生人數 地圖= 「」 「發射(this.school_id,1)」 「」

減少= 「」「功能(鍵,值){VAR total = 0; for(var i = 0; i < values.length; i ++){total + = values [i];} return total;}「」「

+0

還有一件事是用戶應該與每所學校有所不同。上面的代碼工作正常,但在學生id = 1的情況下有3個條目反對學校1然後reurn應該是學校id = 1,count = 1 – user493550

+0

這就是爲什麼即時使用地圖reudce兩次 – user493550

+0

我不知道你的模型,但恕我直言,你必須在地圖中使用一個對象作爲id:map =「」「emit({scid:this.school_id,stid:this.student_id},1)」「」 – nickmilon