MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB, MapReduce e classificação


Em primeiro lugar, o mapa/redução do Mongo não foi projetado para ser usado como uma ferramenta de consulta (como no CouchDB), é projetado para você executar tarefas em segundo plano. Eu uso no trabalho para analisar dados de tráfego.

O que você está fazendo de errado, no entanto, é que você está aplicando o sort() à sua entrada, mas é inútil porque quando o map() etapa é feita os documentos intermediários são ordenados por cada keys . Como sua chave é um documento, ela está sendo classificada por product_id , popularity .

Foi assim que gerei meu conjunto de dados
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 esta minha tarefa map/reduce:
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 este é o resultado final (muito demorado para colar aqui):

http://cesarodas.com/results.txt

Isso funciona porque agora estamos classificando por sorting, product_id, popularity . Você pode brincar com a classificação como quiser, apenas lembre-se de que a classificação final é por key independentemente de como sua entrada é classificada.

De qualquer forma, como eu disse antes, você deve evitar fazer consultas com Map/Reduce, ele foi projetado para processamento em segundo plano. Se eu fosse você, projetaria meus dados de tal forma que pudesse acessá-los com consultas simples, sempre há uma troca neste caso de inserção/atualização complexa para ter consultas simples (é assim que vejo o MongoDB).