MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MapReduce-Funktion in MongoDB – Gruppieren von Dokumenten nach ID

Beim Lernen haben Sie vielleicht die zentrale Handbuchseite auf mapReduce . Es gibt ein wichtiges Stück von Informationen, die Sie entweder verpasst oder nicht gelesen und gelernt haben:

Und dann kurz danach:

Das bedeutet also im Grunde, dass der „Reduzierer“, da er nicht „alle“ eindeutigen Schlüssel auf einmal verarbeitet, dieselbe „Eingabe“ erwartet, wie er „Ausgabe“ liefert, da diese Ausgabe wieder eingespeist werden kann den Reduzierer wieder.

Aus dem gleichen Grund muss der „Mapper“ genau das ausgeben, was als „Reduzierer“-Ausgang erwartet wird, der auch der „Reduzierer“-„Eingang“ ist. Sie "verändern" also die Datenstruktur eigentlich gar nicht, sondern "reduzieren" sie stattdessen nur.

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

Jetzt behandeln Sie die Eingabe als Array, das auch die Ausgabe ist, dann werden die erwarteten Ergebnisse zurückgegeben.

Das nächste, was Sie lernen müssen, ist das in den meisten Fälle mapReduce ist nicht wirklich das, was Sie verwenden möchten, und dass Sie Aggregationsframework stattdessen.

Im Gegensatz zu mapReduce verwendet dies "nativ codierte" Operatoren und benötigt keine JavaScript-Interpretation, um ausgeführt zu werden. Und das bedeutet im Wesentlichen, dass es "schneller" und oft viel einfacher im Aufbau ist.

Hier ist die gleiche Operation mit .aggregate() :

db.Cool.aggregate([
    { "$group": {
        "_id": "$id",
        "cools": { "$push": "$cool" }
    }}
])

Das Gleiche, weniger Codierung und viel schneller.

Für die Ausgabe in eine andere Sammlung verwenden Sie $out :

db.Cool.aggregate([
    { "$group": {
        "_id": "$id",
        "cools": { "$push": "$cool" }
    }},
    { "$out": "reduced" }
])

Fürs Protokoll, hier ist die Ausgabe von mapReduce:

{ "_id" : "a", "value" : { "cools" : [ "a1", "a2" ] } }
{ "_id" : "b", "value" : { "cools" : [ "b1", "b2" ] } }
{ "_id" : "c", "value" : { "cools" : [ "c1" ] } }
{ "_id" : "d", "value" : { "cools" : [ "d1" ] } }

Und die Gesamtleistung. Mit dem einzigen Unterschied zur mapReduce _id und value obligatorische Ausgabe ist, dass die Tasten vertauscht sind, seit $group garantiert keine Reihenfolge (wird aber allgemein als umgekehrter Stapel beobachtet):

{ "_id" : "d", "cools" : [ "d1" ] }
{ "_id" : "c", "cools" : [ "c1" ] }
{ "_id" : "b", "cools" : [ "b1", "b2" ] }
{ "_id" : "a", "cools" : [ "a1", "a2" ] }