También se debe mencionar que, según el documentation, "MongoDB puede invocar la función de reducción más de una vez para la misma clave. En este caso, la salida anterior de la función reducir para esa clave se convertirá en una de las valores de entrada a la siguiente invocación de función de reducción para esa clave. ".
Además, reduce
debe ser asociativa, conmutativa y idempotente:
reduce(key, [ C, reduce(key, [ A, B ]) ]) == reduce(key, [ C, A, B ])
reduce(key, [ reduce(key, valuesArray) ]) == reduce(key, valuesArray)
reduce(key, [ A, B ]) == reduce(key, [ B, A ])
Por lo tanto, significa que la función reduce
debe estar listo para recibir el objeto que es el resultado de la invocación anterior de la misma. Lo cual (al menos para mí, personalmente) significa que la mejor forma de implementar mapReduce
es hacer que la función map
(si es posible) emita valores en el mismo formato que devuelve la función reduce
. Entonces la función reduce
se puede implementar para admitir solo un formato de entrada. Y, como resultado, incluso si solo hay un objeto emitido por map
(y como resultado se omite la invocación de reduce
), en el resultado final de mapReduce
, el valor de las claves para las que nunca se llamó reduce
aún estar en el mismo formato que el valor para el resto de las teclas.
Por ejemplo, si tenemos la siguiente estructura de documento:
{
"foo": <some_string>,
"status": ("foo"|"bar")
}
la función map
puede ser como sigue:
function() {
var value = {
"num_total": 1,
"num_foos": 0,
"num_bars": 0
};
if (this.status == "foo") {
value["num_foos"] += 1;
}
if (this.status == "bar") {
value["num_bars"] += 1;
}
emit(this.foo, value);
}
y la función reduce
será:
function(key, values) {
var reduced = {
"num_total": 0,
"num_foos": 0,
"num_bars": 0
};
values.forEach(function(val) {
reduced["num_total"] += val["num_total"];
reduced["num_foos"] += val["num_foos"];
reduced["num_bars"] += val["num_bars"];
});
return reduced;
}
Tienes razón Tomasz. Escogí este ejemplo de los documentos de MongoDB. Ayudaría a Map/Reduce noobs como yo mucho si esto se mencionara claramente. ¡Un humilde "cheque verde" para ti! – Adil
Aún se puede deducir que reducir recibirá, usando su ejemplo, reducir (_id, ['Map1']) en el caso de solo 1 elemento emitido. No pasar reduce las interrupciones de mi conjunto de resultados. –
Creo que no llamar a reducir en valores individuales es una opción de implementación extraña. Por lo tanto, cada vez que cambie la estructura del resultado de 'map' también tendrá que ajustar' reduce' para obtener resultados uniformes en caso de resultados de 'mapa' de valor único. – Chaquotay