文档菜单
文档首页
/
MongoDB 手册
/ /

调试 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. 使用 myTestValues 调用 reduceFunction1

    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. 使用 myTestObjects 调用 reduceFunction2

    reduceFunction2('myKey', myTestObjects);
  8. 验证 reduceFunction2 返回了一个包含正好 countqty 字段的文档。

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

reduce 函数接收一个 key 和一个 values 数组作为参数。您可以测试 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 }

由于映射-归约操作可能会对同一个键调用多次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. 首先使用myKeyvaluesIdempotent调用reduceFunction2,然后使用myKeyvalues1调用

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

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

返回

调试 Map