学習中に、mapReduce> 。 重要な部分が1つあります 見逃した、または読んだり学んだりしていない情報の一覧:
そしてその少し後に:
つまり、基本的には、「レデューサー」は実際にはすべての一意のキーを一度に処理するわけではないため、「出力」を提供するのと同じ「入力」を期待します。これは、その出力をにフィードバックできるためです。再びレデューサー。
同じ理由で、「マッパー」は、「レデューサー」出力として期待されるものを正確に出力する必要があります。これは、レデューサー「入力」でもあります。したがって、実際にはデータ構造を「変更」するのではなく、代わりに「削減」するだけです。
db.Cool.mapReduce(
function(){emit(this.id, { "cools": [this.cool] })},
function(key, values){
var res = [];
values.forEach(function(cool){
cool.cools.forEach(function(v) {
res.push(v);
});
});
return {cools: res};
},
{out: "MapReduce"}
)
これで、入力を出力でもある配列として処理しているので、期待される結果が返されます。
次に学ぶべきことは、ほとんど ケースmapReduceは実際には使用したいものではなく、集約フレームワーク 代わりに。
mapReduceとは対照的に、これは「ネイティブにコード化された」演算子を使用し、実行するためにJavaScriptの解釈を必要としません。そして、それは主に、それが「より速く」、多くの場合、構造がはるかに単純であることを意味します。
.aggregate()
を使用した同じ操作を次に示します。 :
db.Cool.aggregate([
{ "$group": {
"_id": "$id",
"cools": { "$push": "$cool" }
}}
])
同じことで、コーディングが少なく、はるかに高速です。
使用する別のコレクションへの出力$out
:
db.Cool.aggregate([
{ "$group": {
"_id": "$id",
"cools": { "$push": "$cool" }
}},
{ "$out": "reduced" }
])
記録のために、ここにmapReduceの出力があります:
{ "_id" : "a", "value" : { "cools" : [ "a1", "a2" ] } }
{ "_id" : "b", "value" : { "cools" : [ "b1", "b2" ] } }
{ "_id" : "c", "value" : { "cools" : [ "c1" ] } }
{ "_id" : "d", "value" : { "cools" : [ "d1" ] } }
そして、総出力。 mapReduce _id
との唯一の違いは およびvalue
$group
なので、キーが逆になっているという狂気の出力 順序を保証するものではありません(ただし、通常は逆スタックとして観察されます):
{ "_id" : "d", "cools" : [ "d1" ] }
{ "_id" : "c", "cools" : [ "c1" ] }
{ "_id" : "b", "cools" : [ "b1", "b2" ] }
{ "_id" : "a", "cools" : [ "a1", "a2" ] }