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