2012-03-01 4 views
2

mapreduceを使用してグループ集計を実行したいと思います。ここで は私のマップ機能である:ここでMongoDB MapReduce関数がreduceからの変数を使用しない場合の奇妙な値

function() { 
    emit(this.TransactionType, { Count: 1 }); 
} 

は、2つの機能を減らすことである。

function(key, values) { 
    var result = {Count: 0}; 
    values.forEach(function(value) { 
     result.Count += 1; 
    }); 
    return result; 
} 

function(key, values) { 
    var result = {Count: 0}; 
    values.forEach(function(value) { 
     result.Count += value.Count; 
    }); 
    return result; 
} 

、ここで二つの結果されています

"_id" : "A", "value" : { "Count" : 13.0 } 
"_id" : "B", "value" : { "Count" : 2.0 } 
"_id" : "C", "value" : { "Count" : 1.0 } 
"_id" : "D", "value" : { "Count" : 209.0 } 
"_id" : "E", "value" : { "Count" : 66.0 } 
"_id" : "F", "value" : { "Count" : 11.0 } 
"_id" : "G", "value" : { "Count" : 17.0 } 
"_id" : "H", "value" : { "Count" : 17.0 } 


"_id" : "A", "value" : { "Count" : 128.0 } 
"_id" : "B", "value" : { "Count" : 115.0 } 
"_id" : "C", "value" : { "Count" : 1.0 } 
"_id" : "D", "value" : { "Count" : 3645.0 } 
"_id" : "E", "value" : { "Count" : 1405.0 } 
"_id" : "F", "value" : { "Count" : 256.0 } 
"_id" : "G", "value" : { "Count" : 380.0 } 
"_id" : "H", "value" : { "Count" : 398.0 } 

は、なぜ2つの結果が異なっていますか?

非常

ありがとう

答えて

0

"fold" higher-order functionの点で「減らす」機能を考えると便利です。すなわち、あなたの "reduce"関数は値のリストに加えられ、オブジェクト(例では "result"変数)が累積されます。これは最初に指定されましたが、最終的には連続しての出力に置き換えられますあなたの関数への呼び出し。さらに、関数が適用される値のリストは、任意の数のサブリストに分割することができます。

たとえば、 "fold"高次関数の例であるJavaScript Array "reduce" functionを使用して関数がどのように動作するかを考えます。最初の例では、各要素の「Count」プロパティを使用しないため、不適切な動作をします。削減アレイ#でそれを使用するための連続した試みは、同様に失敗します:

function badReducer(accum, x) { 
    accum.Count += 1; 
    return accum; 
} 
var sum = {Count:0}; 
sum = [{Count:1}, {Count:2}, {Count:3}].reduce(badReducer, sum); 
sum; // => {Count:3}, d'oh! 
sum = [{Count:4}].reduce(badReducer, sum); 
sum; // => {Count:5}, d'oh! 

をしかし、あなたの第二の例は、適切にプロパティを「カウント」と、自身の出力に連続的に適用することができますが追加されています。

function goodReducer(accum, x) { 
    accum.Count += x.Count; 
    return accum; 
} 
var sum = {Count:0}; 
sum = [{Count:1}, {Count:2}, {Count:3}].reduce(goodReducer, sum); 
sum; // => {Count:6}, woohoo! 
sum = [{Count:4}].reduce(goodReducer, sum); 
sum; // => {Count:10}, woohoo! 
+0

ありがとうございました。私はhttp://www.mongodb.org/display/DOCS/MapReduce#MapReduce- ReduceFunctionを慎重に読んでいない – user418727

1

最初の関数を減らすには、各値のためにこれを行います。

result.Count += 1; 

秒1は、この処理を行います。

だから、
result.Count += value.Count; 

、自分の価値観のリストが(1,2,3,4,5)ある場合最初のアイテムは各アイテムに+1を追加し、出力として5を返します。 2番目の値は各項目に+5を追加します(value.Countは5なので)。したがって、5 + 5 + 5 + 5 + 5 = 25を出力します。

1

reduce関数は次のように記述する必要があります。それ自身の出力を新しい入力として使用して数回再実行します。

結果関数は、{_id、[values]}の形式でデータを出力します。あなたの関数を減らす、入力は以下の可能性について:最初の関数で

"A", [{count:1}, {count:2}, {count:3}] 

、カウントは、値のみのアレイ内の各文書のために1ずつ増加し、出力は次のようになります。

"A", {count:3} 
第二の機能で

は、カウンタの値が追加されるので、出力はこれは、あなたが経験しているものです

"A", {count:6} 

になります。 Map Reduce操作の詳細な手順については、MongoDB Cookbookレシピの「Extras」のセクションを参照してください。http://cookbook.mongodb.org/patterns/finding_max_and_min/

幸運と幸せマップ還元!

関連する問題