sql >> Database teknologi >  >> NoSQL >> MongoDB

Sammenlægning af to samlinger i MongoDB

Dette svarer til et spørgsmål, der blev stillet på MongoDB-brugernes Google-grupper.
https://groups.google.com/group/mongodb-user/browse_thread/thread/60a8b683e2626ada?pli=1

Svaret refererer til en online tutorial, der ligner dit eksempel:http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/

For mere information om MapReduce i MongoDB, se venligst dokumentationen:http://www.mongodb.org/display/DOCS/MapReduce

Derudover er der en nyttig trin-for-trin gennemgang af, hvordan en MapReduce-operation fungerer i "Extras"-sektionen i MongoDB Cookbook-artiklen med titlen "Finding Max And Min Values ​​with Versioned Documents":http://cookbook.mongodb. org/patterns/finding_max_and_min/

Undskyld mig, hvis du allerede har læst nogle af de refererede dokumenter. Jeg har inkluderet dem til gavn for andre brugere, der måske læser dette indlæg og er nye til at bruge MapReduce i MongoDB

Det er vigtigt, at output fra 'emit'-sætningerne i kortfunktionerne matcher output fra Reducer-funktionen. Hvis der kun er ét dokument, der udskrives af kortfunktionen, kører funktionen Reducer muligvis slet ikke, og så vil din outputsamling have uoverensstemmende dokumenter.

Jeg har ændret dine kortudsagn en smule for at udsende dokumenter i formatet af dit ønskede output med to separate "klasser"-arrays.
Jeg har også omarbejdet din reduce-sætning for at tilføje nye klasser til classes_1 og classes_2-arrays, kun hvis de findes ikke allerede.

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'}})

Kørsel af de to MapReduce-operationer resulterer i følgende samling, som matcher dit ønskede format:

> 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 udsender altid dokumenter i form af {_id:"id", value:"value"}Der er mere information tilgængelig om at arbejde med underdokumenter i dokumentet med titlen "Dot Notation (Reaching into Objects)":http:/ /www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

Hvis du gerne vil have output fra MapReduce til at blive vist i et andet format, bliver du nødt til at gøre det programmatisk i din applikation.

Forhåbentlig vil dette forbedre din forståelse af MapReduce og bringe dig et skridt tættere på at producere din ønskede outputsamling. Held og lykke!



  1. Gruppér poster efter måned og tæl dem - Mongoose, nodeJs, mongoDb

  2. Hvordan dropper man en database med Mongoose?

  3. Sådan konfigureres SELinux til MongoDB Replica Sets

  4. bedste praksis for django + PyMongo-pooling?