Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

Solução de problemas da função Reduzir

Nesta página

  • Confirmar tipo de saída
  • Garanta a insensibilidade à ordem dos valores mapeados
  • Certifique-se de reduzir a idempotência da função

Observação

Pipeline de Agregação como Alternativa à Redução de Mapa

A partir do MongoDB 5.0, map-reduce está obsoleto:

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 reduce deve retornar um objeto cujo tipo deve ser idêntico ao tipo do value emitido pela função map .

  • A ordem dos elementos no valuesArray não deve afetar a saída da função reduce .

  • a função reduce deve ser idempotente.

Para obter uma lista de todos os requisitos da função reduce , consulte mapReduce ou mongosh método auxiliar db.collection.mapReduce().

Você pode testar que a função reduce retorna um valor que é do mesmo tipo que o valor emitido da função map .

  1. Defina uma função reduceFunction1 que recebe os argumentos keyCustId e valuesPrices. valuesPrices é uma matriz de números inteiros:

    var reduceFunction1 = function(keyCustId, valuesPrices) {
    return Array.sum(valuesPrices);
    };
  2. Defina uma array de amostra de números inteiros:

    var myTestValues = [ 5, 5, 10 ];
  3. Invoque o reduceFunction1 com myTestValues:

    reduceFunction1('myKey', myTestValues);
  4. Verifique se o reduceFunction1 retornou um número inteiro:

    20
  5. Defina uma função reduceFunction2 que recebe os argumentos keySKU e valuesCountObjects. valuesCountObjects é uma matriz de documentos que contêm dois campos count e 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;
    };
  6. Definir uma amostra de array de documentos:

    var myTestObjects = [
    { count: 1, qty: 5 },
    { count: 2, qty: 10 },
    { count: 3, qty: 15 }
    ];
  7. Invoque o reduceFunction2 com myTestObjects:

    reduceFunction2('myKey', myTestObjects);
  8. Verifique se o reduceFunction2 retornou um documento com exatamente o count e o campo qty :

    { "count" : 6, "qty" : 30 }

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 .

  1. Defina uma array de amostra values1 e uma array de amostra values2 que 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 }
    ];
  2. Defina uma função reduceFunction2 que recebe os argumentos keySKU e valuesCountObjects. valuesCountObjects é uma matriz de documentos que contêm dois campos count e 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;
    };
  3. Invoque o reduceFunction2 primeiro com values1 e depois com values2:

    reduceFunction2('myKey', values1);
    reduceFunction2('myKey', values2);
  4. Verifique se o reduceFunction2 retornou o mesmo resultado:

    { "count" : 6, "qty" : 30 }

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 .

  1. Defina uma função reduceFunction2 que recebe os argumentos keySKU e valuesCountObjects. valuesCountObjects é uma matriz de documentos que contêm dois campos count e 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;
    };
  2. Definir uma chave de amostra:

    var myKey = 'myKey';
  3. Defina um array de amostra valuesIdempotent que 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 } ] )
    ];
  4. Defina um array de amostra values1 que combina os valores passados para reduceFunction2:

    var values1 = [
    { count: 1, qty: 5 },
    { count: 2, qty: 10 },
    { count: 3, qty: 15 }
    ];
  5. Invoque o reduceFunction2 primeiro com myKey e valuesIdempotent e depois com myKey e values1:

    reduceFunction2(myKey, valuesIdempotent);
    reduceFunction2(myKey, values1);
  6. Verifique se o reduceFunction2 retornou o mesmo resultado:

    { "count" : 6, "qty" : 30 }
← Solucionar problemas da função de mapa