Docs 菜单

Docs 主页开发应用程序MongoDB Manual

Reduce 函数故障排除

在此页面上

  • 确认输出类型
  • 确保对映射值的顺序不敏感
  • 确保 Reduce 函数幂等

注意

作为 Map-Reduce 替代方案的聚合管道

从 MongoDB 5.0 开始, map-reduce已弃用:

有关 map-reduce 的聚合管道替代方案的示例,请参阅:

聚合管道也比 map-reduce 操作更容易排除故障。

reduce函数是一个 JavaScript 函数,可在map-reduce操作期间将与特定键关联的所有值“减少”为单个对象。 reduce函数必须满足各种要求。 本教程帮助验证reduce函数是否满足以下条件:

  • reduce函数必须返回一个对象,该对象的类型必须map函数发出的value类型相同。

  • valuesArray中元素的顺序不应影响reduce函数的输出。

  • reduce 函数必须是幂等的

有关reduce函数的所有要求的列表,请参阅mapReduce mongosh辅助方法db.collection.mapReduce()

您可以测试reduce函数返回的值是否与map函数发出的值类型相同。

  1. 定义一个reduceFunction1函数,它接受keyCustIdvaluesPrices参数。 valuesPrices是一个整数数组:

    var reduceFunction1 = function(keyCustId, valuesPrices) {
    return Array.sum(valuesPrices);
    };
  2. 定义一个整数样本数组:

    var myTestValues = [ 5, 5, 10 ];
  3. 使用reduceFunction1 调用myTestValues

    reduceFunction1('myKey', myTestValues);
  4. 验证reduceFunction1返回的整数:

    20
  5. 定义一个reduceFunction2函数,它接受keySKUvaluesCountObjects参数。 valuesCountObjects是包含两个字段countqty的文档数组:

    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. 定义文档样本数组:

    var myTestObjects = [
    { count: 1, qty: 5 },
    { count: 2, qty: 10 },
    { count: 3, qty: 15 }
    ];
  7. 使用reduceFunction2 调用myTestObjects

    reduceFunction2('myKey', myTestObjects);
  8. 验证reduceFunction2返回的文档是否准确包含countqty字段:

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

reduce函数将keyvalues数组作为参数。 您可以测试reduce函数的结果是否不依赖于values数组中元素的顺序。

  1. 定义样本values1数组和样本values2数组,仅数组元素顺序不同:

    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. 定义一个reduceFunction2函数,它接受keySKUvaluesCountObjects参数。 valuesCountObjects是包含两个字段countqty的文档数组:

    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. 首先使用values1调用reduceFunction2 ,然后使用values2调用:

    reduceFunction2('myKey', values1);
    reduceFunction2('myKey', values2);
  4. 验证reduceFunction2返回相同的结果:

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

由于 map-reduce 操作可能会为同一键多次调用reduce ,并且不会为工作集中键的单个实例调用reduce ,因此reduce函数必须返回以下值:与map函数发出的值的类型相同。您可以测试reduce函数是否会在不影响最终值的情况下处理“缩减后的”值。

  1. 定义一个reduceFunction2函数,它接受keySKUvaluesCountObjects参数。 valuesCountObjects是包含两个字段countqty的文档数组:

    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. 定义示例键:

    var myKey = 'myKey';
  3. 定义一个样本valuesIdempotent数组,其中包含一个元素,该元素是对reduceFunction2函数的调用:

    var valuesIdempotent = [
    { count: 1, qty: 5 },
    { count: 2, qty: 10 },
    reduceFunction2(myKey, [ { count:3, qty: 15 } ] )
    ];
  4. 定义一个示例values1数组,用于合并传递给reduceFunction2的值:

    var values1 = [
    { count: 1, qty: 5 },
    { count: 2, qty: 10 },
    { count: 3, qty: 15 }
    ];
  5. reduceFunction2首先使用myKey valuesIdempotentmyKey和 ,然后使用 和 调用values1

    reduceFunction2(myKey, valuesIdempotent);
    reduceFunction2(myKey, values1);
  6. 验证reduceFunction2返回相同的结果:

    { "count" : 6, "qty" : 30 }
← Map 函数故障排除