Toto je podobná otázka, která byla položena ve Skupinách Google uživatelů MongoDB.
https://groups.google.com/group/mongodb-user/browse_thread/thread/60a8b683e2626ada?pli=1
Odpověď odkazuje na online tutoriál, který vypadá podobně jako váš příklad:http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/
Další informace o MapReduce v MongoDB naleznete v dokumentaci:http://www.mongodb.org/display/DOCS/MapReduce
Kromě toho je užitečný podrobný návod, jak funguje operace MapReduce, v části „Extras“ článku kuchařky MongoDB s názvem „Hledání maximálních a minimálních hodnot pomocí verzovaných dokumentů“:http://cookbook.mongodb. org/patterns/finding_max_and_min/
Promiňte, pokud jste si již přečetli některé z uvedených dokumentů. Zahrnul jsem je ve prospěch ostatních uživatelů, kteří možná čtou tento příspěvek a začínají používat MapReduce v MongoDB
Je důležité, aby výstupy z příkazů 'emit' ve funkcích Map odpovídaly výstupům funkce Reduce. Pokud existuje pouze jeden výstup dokumentu pomocí funkce Map, funkce Reduce nemusí být spuštěna vůbec a vaše kolekce výstupů bude mít neshodné dokumenty.
Mírně jsem upravil vaše příkazy map tak, aby vysílaly dokumenty ve formátu požadovaného výstupu se dvěma samostatnými poli "classes".
Přepracoval jsem také váš příkaz snížení tak, aby do polí class_1 a class_2 přidal nové třídy, pouze pokud již neexistují.
var mapDetails = function(){
var output = {studentid: this.studentid, classes_1: [], classes_2: [], year: this.year, overall: 0, subscore: 0}
if (this.year == 1) {
output.classes_1 = this.classes;
}
if (this.year == 2) {
output.classes_2 = this.classes;
}
emit(this.studentid, output);
};
var mapGpas = function() {
emit(this.studentid, {studentid: this.studentid, classes_1: [], classes_2: [], year: 0, overall: this.overall, subscore: this.subscore});
};
var r = function(key, values) {
var outs = { studentid: "0", classes_1: [], classes_2: [], overall: 0, subscore: 0};
values.forEach(function(v){
outs.studentid = v.studentid;
v.classes_1.forEach(function(class){if(outs.classes_1.indexOf(class)==-1){outs.classes_1.push(class)}})
v.classes_2.forEach(function(class){if(outs.classes_2.indexOf(class)==-1){outs.classes_2.push(class)}})
if (v.year == 0) {
outs.overall = v.overall;
outs.subscore = v.subscore;
}
});
return outs;
};
res = db.details.mapReduce(mapDetails, r, {out: {reduce: 'joined'}})
res = db.gpas.mapReduce(mapGpas, r, {out: {reduce: 'joined'}})
Spuštěním dvou operací MapReduce vznikne následující kolekce, která odpovídá požadovanému formátu:
> db.joined.find()
{ "_id" : "12345a", "value" : { "studentid" : "12345a", "classes_1" : [ 1, 17, 19, 21 ], "classes_2" : [ 32, 91, 101, 217 ], "overall" : 97, "subscore" : 1 } }
{ "_id" : "24680a", "value" : { "studentid" : "24680a", "classes_1" : [ 1, 11, 18, 22 ], "classes_2" : [ ], "overall" : 76, "subscore" : 2 } }
{ "_id" : "98765a", "value" : { "studentid" : "98765a", "classes_1" : [ 2, 12, 19, 22 ], "classes_2" : [ 32, 99, 110, 215 ], "overall" : 85, "subscore" : 5 } }
>
MapReduce vždy vypisuje dokumenty ve tvaru {_id:"id", value:"value"}Další informace o práci s dílčími dokumenty jsou k dispozici v dokumentu s názvem "Dot Notation (Reaching into Objects)":http:/ /www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
Pokud chcete, aby se výstup MapReduce objevil v jiném formátu, budete to muset udělat programově ve vaší aplikaci.
Doufejme, že to zlepší vaše porozumění MapReduce a přiblíží vás o krok blíže k vytvoření požadované výstupní kolekce. Hodně štěstí!