Nota
Pipeline de agregación como alternativa a Map-Reduce
A partir de MongoDB 5.0, El map-reduce está en desuso:
En lugar de map-reduce, debería usar una canalización de agregación. Las canalizaciones de agregación ofrecen mejor rendimiento y usabilidad que map-reduce.
Puedes reescribir las operaciones de map-reduce usando etapas del pipeline de agregación, como
$group,$mergey otros.Para las operaciones map-reduce que requieren una funcionalidad personalizada, puedes utilizar los operadores de agregación
$accumulatory$function. Puedes utilizar esos operadores para definir expresiones de agregación personalizadas en JavaScript.
Para ejemplos de alternativas de pipeline de agregación a map-reduce, consulte:
Una canalización de agregación también es más fácil de solucionar que una operación de mapa-reducción.
La función reduce es una función de JavaScript que "reduce" todos los valores asociados a una clave particular a un solo objeto durante una operación de map-reduce. La función reduce debe cumplir varios requisitos. Este tutorial ayuda a verificar que la función reduce cumpla con los siguientes criterios:
La
reducefunción debe retornar un objeto cuyo tipo debe ser idéntico al tipo delvalueemitido por la funciónmap.El orden de los elementos en la
valuesArrayno debe afectar la salida de la funciónreduce.La función
reducedebe ser idempotente.
Para obtener una lista de todos los requisitos para la función reduce, consulta mapReduce o mongosh método db.collection.mapReduce() auxiliar.
Confirme el tipo de salida
Puede probar que la función reduce devuelve un valor que es del mismo tipo que el valor emitido por la función map.
Define una función
reduceFunction1que tome los argumentoskeyCustIdyvaluesPrices.valuesPriceses un arreglo de enteros:var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; Definir un arreglo de enteros de muestra:
var myTestValues = [ 5, 5, 10 ]; Invoca el
reduceFunction1conmyTestValues:reduceFunction1('myKey', myTestValues); Verifique que el
reduceFunction1devolvió un número entero:20 Define una función
reduceFunction2que toma los argumentoskeySKUyvaluesCountObjects.valuesCountObjectses una matriz de documentos que contienen dos camposcountyqty:var reduceFunction2 = function(keySKU, valuesCountObjects) { reducedValue = { count: 0, qty: 0 }; for (var idx = 0; idx < valuesCountObjects.length; idx++) { reducedValue.count += valuesCountObjects[idx].count; reducedValue.qty += valuesCountObjects[idx].qty; } return reducedValue; }; Defina una matriz de muestra de documentos:
var myTestObjects = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, { count: 3, qty: 15 } ]; Invoca el
reduceFunction2conmyTestObjects:reduceFunction2('myKey', myTestObjects); Verifique que
reduceFunction2haya devuelto un documento con exactamente los camposcountyqty:{ "count" : 6, "qty" : 30 }
Asegurar la insensibilidad al orden de los valores mapeados
La función reduce toma un key y un arreglo values como argumento. Puedes verificar que el resultado de la función reduce no depende del orden de los elementos en el arreglo values.
Define una matriz de muestra
values1y una matriz de muestravalues2que solo difieren en el orden de los elementos de la matriz:var values1 = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, { count: 3, qty: 15 } ]; var values2 = [ { count: 3, qty: 15 }, { count: 1, qty: 5 }, { count: 2, qty: 10 } ]; Define una función
reduceFunction2que toma los argumentoskeySKUyvaluesCountObjects.valuesCountObjectses una matriz de documentos que contienen dos camposcountyqty:var reduceFunction2 = function(keySKU, valuesCountObjects) { reducedValue = { count: 0, qty: 0 }; for (var idx = 0; idx < valuesCountObjects.length; idx++) { reducedValue.count += valuesCountObjects[idx].count; reducedValue.qty += valuesCountObjects[idx].qty; } return reducedValue; }; Invoque primero
reduceFunction2convalues1y luego convalues2:reduceFunction2('myKey', values1); reduceFunction2('myKey', values2); Verifique que
reduceFunction2haya devuelto el mismo resultado:{ "count" : 6, "qty" : 30 }
Asegurar la idempotencia de la función reducir
Como la operación map-reduce puede llamar a reduce varias veces para la misma clave, y no llamará a un reduce para instancias individuales de una clave en el conjunto de trabajo, la función reduce debe devolver un valor del mismo tipo que el valor emitido por la función map. Puedes probar que la función reduce procesa valores "reducidos" sin afectar el valor final.
Define una función
reduceFunction2que toma los argumentoskeySKUyvaluesCountObjects.valuesCountObjectses una matriz de documentos que contienen dos camposcountyqty:var reduceFunction2 = function(keySKU, valuesCountObjects) { reducedValue = { count: 0, qty: 0 }; for (var idx = 0; idx < valuesCountObjects.length; idx++) { reducedValue.count += valuesCountObjects[idx].count; reducedValue.qty += valuesCountObjects[idx].qty; } return reducedValue; }; Definir una clave de muestra:
var myKey = 'myKey'; Define un arreglo de ejemplo de
valuesIdempotentque contenga un elemento que sea una llamada a la funciónreduceFunction2:var valuesIdempotent = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, reduceFunction2(myKey, [ { count:3, qty: 15 } ] ) ]; Define una matriz de muestra
values1que combina los valores pasados areduceFunction2:var values1 = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, { count: 3, qty: 15 } ]; Invoque el
reduceFunction2primero conmyKeyyvaluesIdempotenty luego conmyKeyyvalues1:reduceFunction2(myKey, valuesIdempotent); reduceFunction2(myKey, values1); Verifique que
reduceFunction2haya devuelto el mismo resultado:{ "count" : 6, "qty" : 30 }