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

MongoDB, MapReduce und Sortierung

Zunächst einmal sind Mongo map/reduce nicht als Abfragetool konzipiert (wie es in CouchDB der Fall ist), sondern für die Ausführung von Hintergrundaufgaben. Ich verwende es bei der Arbeit, um Verkehrsdaten zu analysieren.

Was Sie jedoch falsch machen, ist, dass Sie sort() auf Ihre Eingabe anwenden, aber es ist nutzlos, weil wenn map() Wenn die Phase abgeschlossen ist, werden die Zwischendokumente nach den einzelnen keys sortiert . Da Ihr Schlüssel ein Dokument ist, wird er nach product_id sortiert , popularity .

So habe ich meinen Datensatz generiert

function generate_dummy_data() {
    for (i=2; i < 1000000; i++) { 
        db.foobar.save({
          _id: i, 
         category_id: parseInt(Math.random() * 30), 
         popularity:    parseInt(Math.random() * 50)
        }) 
    }
}

Und das ist meine Map/Reduce-Aufgabe:

var data = db.runCommand({
  'mapreduce': 'foobar',
  'map': function() {
    emit({
      sorting: this.popularity * -1,
      product_id: this._id,
      popularity: this.popularity,
    }, 1);
  },
  'reduce': function(key, values) {
    var sum = 0;
    values.forEach(function(v) {
      sum += v;
    });

    return sum;  
  },
  'query': {category_id: 20},
  'out': {inline: 1},
});

Und das ist das Endergebnis (sehr lang, um es hier einzufügen):

http://cesarodas.com/results.txt

Das funktioniert, weil wir jetzt nach sorting, product_id, popularity sortieren . Sie können mit der Sortierung spielen, wie Sie möchten, denken Sie daran, dass die endgültige Sortierung nach key erfolgt unabhängig davon, wie Ihre Eingabe sortiert wird.

Wie ich bereits sagte, sollten Sie es vermeiden, Abfragen mit Map/Reduce durchzuführen, es wurde für die Hintergrundverarbeitung entwickelt. Wenn ich Sie wäre, würde ich meine Daten so gestalten, dass ich mit einfachen Abfragen darauf zugreifen könnte. In diesem Fall gibt es immer einen Kompromiss zwischen komplexen Einfügungen/Aktualisierungen und einfachen Abfragen (so sehe ich MongoDB).