sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB, MapReduce y clasificación

En primer lugar, Mongo map/reduce no está diseñado para usarse como una herramienta de consulta (como lo está en CouchDB), está diseñado para ejecutar tareas en segundo plano. Lo uso en el trabajo para analizar datos de tráfico.

Sin embargo, lo que está haciendo mal es que está aplicando sort() a su entrada, pero es inútil porque cuando map() se realiza la etapa se ordenan los documentos intermedios por cada keys . Debido a que su clave es un documento, se ordena por product_id , popularity .

Así es como generé mi conjunto de datos

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

Y esta es mi tarea mapear/reducir:

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

Y este es el resultado final (muy largo para pegarlo aquí):

http://cesarodas.com/resultados.txt

Esto funciona porque ahora estamos ordenando por sorting, product_id, popularity . Puedes jugar con la clasificación como quieras, solo recuerda que la clasificación final es por key independientemente de cómo se ordene su entrada.

De todos modos, como dije antes, debe evitar hacer consultas con Map/Reduce, ya que fue diseñado para el procesamiento en segundo plano. Si yo fuera usted, diseñaría mis datos de tal manera que pudiera acceder a ellos con consultas simples, siempre hay una compensación en este caso, insertos/actualizaciones complejos para tener consultas simples (así es como veo MongoDB).