Observação
Pipeline de Agregação como Alternativa à Redução de Mapa
A partir do MongoDB , 5.0, map-reduce está obsoleto:
- Em vez de map-reduce, você deve usar um aggregation pipeline. aggregation pipeline fornece melhor desempenho e usabilidade do que a redução de mapa. 
- Você pode reescrever operações de redução de mapa utilizando estágios do pipeline de agregação, como - $group,- $mergee outros.
- Nas operações de map-reduce que exigem funcionalidade personalizada, você pode usar os operadores de agregação - $accumulatore- $function. Você pode usar esses operadores para definir expressões de agregação personalizadas no JavaScript.
Para obter exemplos de alternativas de aggregation pipeline para map-reduce, consulte:
Um aggregation pipeline também é mais fácil de solucionar problemas do que uma operação de map-reduce.
A função reduce é uma função JavaScript que "reduz" a um único objeto todos os valores associados a uma chave específica durante uma operação map-reduce . A função reduce deve atender a vários requisitos. Este tutorial ajuda a verificar se a função reduce atende aos seguintes critérios:
- A função - reducedeve retornar um objeto cujo tipo deve ser idêntico ao tipo do- valueemitido pela função- map.
- A ordem dos elementos no - valuesArraynão deve afetar a saída da função- reduce.
- a função - reducedeve ser idempotente.
Para obter uma lista de todos os requisitos para a função reduce , consulte mapReduce ou mongosh método auxiliar db.collection.mapReduce().
Confirmar tipo de saída
Você pode testar que a função reduce retorna um valor que é do mesmo tipo que o valor emitido da função map .
- Defina uma função - reduceFunction1que recebe os argumentos- keyCustIde- valuesPrices.- valuesPricesé uma matriz de números inteiros:- var reduceFunction1 = function(keyCustId, valuesPrices) { - return Array.sum(valuesPrices); - }; 
- Defina uma array de amostra de números inteiros: - var myTestValues = [ 5, 5, 10 ]; 
- Invoque o - reduceFunction1com- myTestValues:- reduceFunction1('myKey', myTestValues); 
- Verifique se o - reduceFunction1retornou um número inteiro:- 20 
- Defina uma função - reduceFunction2que recebe os argumentos- keySKUe- valuesCountObjects.- valuesCountObjectsé uma matriz de documentos que contêm dois campos- counte- qty:- 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 uma amostra de array de documentos: - var myTestObjects = [ - { count: 1, qty: 5 }, - { count: 2, qty: 10 }, - { count: 3, qty: 15 } - ]; 
- Invoque o - reduceFunction2com- myTestObjects:- reduceFunction2('myKey', myTestObjects); 
- Verifique se o - reduceFunction2retornou um documento com exatamente o- counte o campo- qty:- { "count" : 6, "qty" : 30 } 
Garanta a insensibilidade à ordem dos valores mapeados
A função reduce usa uma array key e uma array values como argumento. Você pode testar que o resultado da função reduce não depende da ordem dos elementos na array values .
- Defina uma array de amostra - values1e uma array de amostra- values2que diferem apenas na ordem dos elementos da array:- 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 } - ]; 
- Defina uma função - reduceFunction2que recebe os argumentos- keySKUe- valuesCountObjects.- valuesCountObjectsé uma matriz de documentos que contêm dois campos- counte- qty:- 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 o - reduceFunction2primeiro com- values1e depois com- values2:- reduceFunction2('myKey', values1); - reduceFunction2('myKey', values2); 
- Verifique se o - reduceFunction2retornou o mesmo resultado:- { "count" : 6, "qty" : 30 } 
Certifique-se de reduzir a idempotência da função
Como a operação de map-reduce pode chamar um reduce várias vezes para a mesma chave e não chamará um reduce para instâncias únicas de uma chave no conjunto de trabalho, a função reduce deve retornar um valor do mesmo tipo que o valor emitido da função map . Você pode testar se a função reduce processa valores "reduzidos" sem afetar o valor final .
- Defina uma função - reduceFunction2que recebe os argumentos- keySKUe- valuesCountObjects.- valuesCountObjectsé uma matriz de documentos que contêm dois campos- counte- qty:- 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 uma chave de amostra: - var myKey = 'myKey'; 
- Defina um array de amostra - valuesIdempotentque contém um elemento que é uma chamada para a função- reduceFunction2:- var valuesIdempotent = [ - { count: 1, qty: 5 }, - { count: 2, qty: 10 }, - reduceFunction2(myKey, [ { count:3, qty: 15 } ] ) - ]; 
- Defina um array de amostra - values1que combina os valores passados para- reduceFunction2:- var values1 = [ - { count: 1, qty: 5 }, - { count: 2, qty: 10 }, - { count: 3, qty: 15 } - ]; 
- Invoque o - reduceFunction2primeiro com- myKeye- valuesIdempotente depois com- myKeye- values1:- reduceFunction2(myKey, valuesIdempotent); - reduceFunction2(myKey, values1); 
- Verifique se o - reduceFunction2retornou o mesmo resultado:- { "count" : 6, "qty" : 30 }