Em seu aprendizado, você pode ter perdido a página principal do manual em mapReduce . Existe uma peça vital de informações que você perdeu ou não leu e aprendeu:
E um pouco depois disso:
Então, o que isso basicamente significa é que, como o "redutor" não processa "todas" as chaves exclusivas de uma só vez, ele espera a mesma "entrada" que fornece "saída", uma vez que essa saída pode ser realimentada em o redutor novamente.
Pela mesma razão, o "mapeador" precisa produzir exatamente o que é esperado como a saída do "redutor", que também é a "entrada" do redutor. Portanto, você não "altera" a estrutura de dados, mas apenas a "reduz".
db.Cool.mapReduce(
function(){emit(this.id, { "cools": [this.cool] })},
function(key, values){
var res = [];
values.forEach(function(cool){
cool.cools.forEach(function(v) {
res.push(v);
});
});
return {cools: res};
},
{out: "MapReduce"}
)
Agora você está manipulando a entrada como um array que também é a saída, então os resultados esperados são retornados.
A próxima coisa a aprender é que na maioria casos mapReduce não é realmente o que você quer usar, e que você deveria estar usando o estrutura de agregação em vez de.
Ao contrário de mapReduce, ele usa operadores "codificados nativamente" e não precisa de interpretação de JavaScript para ser executado. E isso significa em grande parte que é "mais rápido" e muitas vezes muito mais simples na construção.
Aqui está a mesma operação com
.aggregate()
:db.Cool.aggregate([
{ "$group": {
"_id": "$id",
"cools": { "$push": "$cool" }
}}
])
Mesma coisa, menos codificação e muito mais rápido.
Ao enviar para outra coleção, você usa
$out
:db.Cool.aggregate([
{ "$group": {
"_id": "$id",
"cools": { "$push": "$cool" }
}},
{ "$out": "reduced" }
])
Para o registro, aqui está a saída mapReduce:
{ "_id" : "a", "value" : { "cools" : [ "a1", "a2" ] } }
{ "_id" : "b", "value" : { "cools" : [ "b1", "b2" ] } }
{ "_id" : "c", "value" : { "cools" : [ "c1" ] } }
{ "_id" : "d", "value" : { "cools" : [ "d1" ] } }
E a produção agregada. Com a única diferença do mapReduce
_id
e value
saída obrigatória sendo que as chaves estão invertidas, pois $group
não garante um pedido (mas geralmente é observado como uma pilha reversa):{ "_id" : "d", "cools" : [ "d1" ] }
{ "_id" : "c", "cools" : [ "c1" ] }
{ "_id" : "b", "cools" : [ "b1", "b2" ] }
{ "_id" : "a", "cools" : [ "a1", "a2" ] }