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

MongoDB, MapReduce e ordinamento

Prima di tutto, Mongo map/reduce non è progettato per essere utilizzato come strumento di query (come in CouchDB), è progettato per eseguire attività in background. Lo uso al lavoro per analizzare i dati sul traffico.

Quello che stai sbagliando, tuttavia, è che stai applicando sort() al tuo input, ma è inutile perché quando map() fase è fatto i documenti intermedi sono ordinati per ogni keys . Poiché la tua chiave è un documento, viene ordinata per product_id , popularity .

È così che ho generato il mio set di dati

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

E questo è il mio compito di mappare/ridurre:

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},
});

E questo è il risultato finale (molto lungo per incollarlo qui):

http://cesarodas.com/results.txt

Funziona perché ora stiamo ordinando per sorting, product_id, popularity . Puoi giocare con l'ordinamento come preferisci, ricorda solo che l'ordinamento finale è per key indipendentemente da come è ordinato il tuo input.

Ad ogni modo, come ho detto prima, dovresti evitare di fare query con Map/Reduce, è stato progettato per l'elaborazione in background. Se fossi in te, progetterei i miei dati in modo tale da potervi accedere con query semplici, c'è sempre un compromesso in questo caso inserimenti/aggiornamenti complessi per avere query semplici (è così che vedo MongoDB).