验证Reduce函数¶
On this page
reduce是用 JavaScript 编写的函数。它在 map-reduce 操作中可以把一个键的所有值合并到一个单独的对象中。 reduce 函数必须满足一系列的要求。本章节介绍如何验证 reduce 函数是否满足了这些场景:
reduce函数返回的对象类型必须和map函数提交的对象类型一样。
数组 valuesArray 中元素的顺序不应该影响 reduce 函数的输出结果。
reduce函数必须是 幂等 。
reduce函数必须要满足几个条件,详细的列表可以查看 mapReduce ,或者 mongo 命令行下的 db.collection.mapReduce() 。
确认输出的类型¶
你可以验证一下 reduce 函数返回的对象类型是否和 map 提交的类型是一样的。
定义 reduceFunction1 函数,它的入参是两个参数 keyCustId 和 valuesPrices。其中 valuesPrices 是一个整形变量数组:
var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); };
定义一个整型变量的数组:
var myTestValues = [ 5, 5, 10 ];
把 myTestValues 传入 reduceFunction1 :
reduceFunction1('myKey', myTestValues);
检查 reduceFunction1 返回的整型值:
20
定义一个函数 reduceFunction2 ,它的入参是 keySKU 和 valuesCountObjects。valuesCountObjects 是一个数组,数组中的每个文档包含两个字段 count 和 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; };
定义一个文档数组:
var myTestObjects = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, { count: 3, qty: 15 } ];
把 myTestObjects 数组传入 reduceFunction2 :
reduceFunction2('myKey', myTestObjects);
检查 reduceFunction2 函数返回的文档中的 count 和 qty 的值:
{ "count" : 6, "qty" : 30 }
对映射的值排序时不区分大小写¶
reduce的入参是一个 key 和数组 values ,你可以测试验证 reduce 的输出结果与 values 数组中元素的顺序是无关的。
定义两个数组 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 } ];
定义一个函数 reduceFunction2 ,它的入参是 keySKU 和 valuesCountObjects。valuesCountObjects 是一个数组,数组中的每个文档包含两个字段 count 和 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; };
依次对 values1 和 values2 调用 reduceFunction2 :
reduceFunction2('myKey', values1); reduceFunction2('myKey', values2);
检查 reduceFunction2 函数两次的返回值是否都是下面的值:
{ "count" : 6, "qty" : 30 }
确保Reduce函数是幂等的¶
由于在整个map-reduce过程中,对于同一个键值可能会调用多次 reduce ,但是输出到结果集的记录不会调用 reduce 。并且 reduce 返回的值类型和 map 提交的值类型一样。你可以测试一下 reduce 函数在调用多次的时候,不会影响最终的值:
定义一个函数 reduceFunction2 ,它的入参是 keySKU 和 valuesCountObjects。valuesCountObjects 是一个数组,数组中的每个文档包含两个字段 count 和 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; };
定义一个键:
var myKey = 'myKey';
定义接下来 reduceFunction2 函数要处理的一个数组 valuesIdempotent :
var valuesIdempotent = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, reduceFunction2(myKey, [ { count:3, qty: 15 } ] ) ];
定义包含了这些值的一个数组 values1 :
var values1 = [ { count: 1, qty: 5 }, { count: 2, qty: 10 }, { count: 3, qty: 15 } ];
首先使用 reduceFunction2 处理 myKey 和 valuesIdempotent ,然后再处理 myKey 和 values1:
reduceFunction2(myKey, valuesIdempotent); reduceFunction2(myKey, values1);
检查 reduceFunction2 函数两次的返回值是否都是下面的值:
{ "count" : 6, "qty" : 30 }