私はMongoDBでMapReduceを使用していますが、まだ理解していない1つの部分を除いて、すべてに頭を悩ませていると思います。何回reduce
実行されますか?
たとえば、それぞれに「カテゴリ」がある「アイテム」のコレクションがあります。これはテストデータです(node.jsユニットテスト用にjavascriptで記述されています):
var i = 0;
var dummyCategories = [
{ categoryId:(++i), categoryName:'Category '+i }, // [0] 1
{ categoryId:(++i), categoryName:'Category '+i }, // [1] 2
{ categoryId:(++i), categoryName:'Category '+i }, // [2] 3
{ categoryId:(++i), categoryName:'Category '+i }, // [3] 4
{ categoryId:(++i), categoryName:'Category '+i } // [4] 5
];
i=0;
var dummyItems = [
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [0] 1
category: dummyCategories[0]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [1] 2
category: dummyCategories[1]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [2] 3
category: dummyCategories[2]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [3] 4
category: dummyCategories[3]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [4] 5
category: dummyCategories[4]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [5] 6
category: dummyCategories[0]
}
];
6つのアイテム、5つのカテゴリがあり、1つは2回表示され、残りは1回表示されます。
私のmap
関数では、を放出して(this.category.categoryId, { items: 1 });
います。(これのフルバージョンには、アイテム数以外の値オブジェクトの他のメトリックが含まれていますが、この動作はどちらの方法でも同じです。)
私のreduce
関数は次のようになります。
function reduce(key, values) {
var totals = {
items: 0
};
for (var i = 0; i < values.length; i++) {
totals.items += values[i].items;
}
return totals;
};
(出力構造は、必要に応じて、マップでもreduceと同じです。)
だから私はこれをmapReduceで実行するとverbose=true
、次の統計が表示されます。
カウント:{出力:5、放出:6、削減:1、入力:6}
input:6は理にかなっています、6つのドキュメントがあります。放出:6は理にかなっており、ドキュメントごとに1つのカテゴリを放出します。output:5は理にかなっており、5つのカテゴリがあります。しかし、なぜreducerunを1回だけ実行したのでしょうか。
これを今書き出すと、複数回出現する放出されたキーごとにreduceが実行されているようです。したがって、キーが1回だけ発行された場合、それは減少しません。あれは正しいですか?実行回数を減らす回数を決定するための数式は何でしょうか?
ありがとうございました!