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

Gruppering af dokumenter i par ved hjælp af mongo-aggregering

Dette er noget, der bare ikke kan gøres med aggregeringsrammerne, og den eneste nuværende MongoDB-metode, der er tilgængelig til denne type operation, er mapReduce.

Årsagen er, at en aggregeringsramme ikke har nogen måde at henvise til noget andet dokument i pipelinen end det nuværende. Dette gælder faktisk også for "gruppering" pipeline stadier, da selvom tingene er grupperet på en "nøgle", kan du ikke rigtig håndtere individuelle dokumenter på den måde, du ønsker.

MapReduce på den anden side har en funktion tilgængelig, der giver dig mulighed for at gøre, hvad du vil her, og det er ikke engang "direkte" relateret til aggregering. Det er faktisk evnen til at have "globalt scopede variabler" på tværs af alle stadier. Og at have en "variabel" til grundlæggende at "gemme det sidste dokument" er alt hvad du behøver for at opnå dit resultat.

Så det er ret simpel kode, og der er faktisk ingen "reduktion" påkrævet:

db.collection.mapReduce(
    function () {
      if (lastVal != null)
        emit( this._id, this.val - lastVal );
      lastVal = this.val;
    },
    function() {}, // mapper is not called
    {
        "scope": { "lastVal": null },
        "out": { "inline": 1 }
    }
)
 

Hvilket giver dig et resultat meget som dette:

{ "results" : [ { "_id" : ObjectId("54a425a99b8bcd6f73e2d662"), "value" : 2 }, { "_id" : ObjectId("54a425a99b8bcd6f73e2d663"), "value" : 3 }, { "_id" : ObjectId("54a425a99b8bcd6f73e2d664"), "value" : 4 } ], "timeMillis" : 3, "counts" : { "input" : 4, "emit" : 3, "reduce" : 0, "output" : 3 }, "ok" : 1 }

Det er egentlig bare at vælge "noget unikt" som det udsendte _id værdi snarere end noget specifikt, fordi alt, hvad dette egentlig gør, er forskellen mellem værdier på forskellige dokumenter.

Globale variabler er normalt løsningen på disse typer af "parring" aggregeringer eller frembringelse af "løbende totaler". Lige nu har aggregeringsrammen ingen adgang til globale variabler, selvom det godt kunne være rart at have. MapReduce-rammen har dem, så det er nok rimeligt at sige, at de også skal være tilgængelige for aggregeringsrammen.

Lige nu er de dog ikke, så hold dig til mapReduce.




  1. MongoDB $sampleRate

  2. Hvordan kan jeg designe skema til nedenstående produkt ved hjælp af mongoose?

  3. Installation af Redis på CentOS 7

  4. Hvordan gemmer man en række objekter i Redis?