I din læring er du måske gået glip af den centrale manualside på mapReduce . Der er én vigtig brik information, som du enten gik glip af eller ikke har læst og lært:
Og så lidt efter det:
Så hvad det grundlæggende betyder er, at fordi "reduceren" faktisk ikke behandler "alle" de unikke nøgler på én gang, så forventer den det samme "input", som det giver "output", da det output kan føres tilbage til reduktionen igen.
Af samme grund skal "mapper" udlæse præcis det, der forventes som "reducer" output, som også er reducer "input". Så du "ændrer" faktisk slet ikke datastrukturen, men "reducerer" den i stedet for.
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"}
)
Nu håndterer du inputtet som et array, som også er outputtet, så returneres de forventede resultater.
Den næste ting at lære er, at i de fleste cases mapReduce er ikke rigtig, hvad du vil bruge, og at du skal bruge aggregeringsramme i stedet.
I modsætning til mapReduce bruger denne "native kodede" operatorer og behøver ikke JavaScript-fortolkning for at køre. Og det betyder i høj grad, at den er "hurtigere" og ofte meget mere enkel i konstruktionen.
Her er den samme operation med .aggregate()
:
db.Cool.aggregate([
{ "$group": {
"_id": "$id",
"cools": { "$push": "$cool" }
}}
])
Det samme, mindre kodning og meget hurtigere.
Output til en anden samling bruger du $out
:
db.Cool.aggregate([
{ "$group": {
"_id": "$id",
"cools": { "$push": "$cool" }
}},
{ "$out": "reduced" }
])
For god ordens skyld er her kortet Reducer output:
{ "_id" : "a", "value" : { "cools" : [ "a1", "a2" ] } }
{ "_id" : "b", "value" : { "cools" : [ "b1", "b2" ] } }
{ "_id" : "c", "value" : { "cools" : [ "c1" ] } }
{ "_id" : "d", "value" : { "cools" : [ "d1" ] } }
Og det samlede output. Med den eneste forskel fra mapReduce _id
og value
Madatorisk output er, at nøglerne er omvendt, da $group
garanterer ikke en ordre (men er generelt set som en omvendt stack):
{ "_id" : "d", "cools" : [ "d1" ] }
{ "_id" : "c", "cools" : [ "c1" ] }
{ "_id" : "b", "cools" : [ "b1", "b2" ] }
{ "_id" : "a", "cools" : [ "a1", "a2" ] }