Map-Reduce Examples
在本页面
在mongo shell 中,db.collection.mapReduce()方法是mapReduce命令的包装。以下示例使用db.collection.mapReduce()方法:
请考虑对包含以下原型文档的集合orders
进行以下 map-reduce 操作:
{
_id: ObjectId("50a8240b927d5d8b5891743c"),
cust_id: "abc123",
ord_date: new Date("Oct 04, 2012"),
status: 'A',
price: 25,
items: [ { sku: "mmm", qty: 5, price: 2.5 },
{ sku: "nnn", qty: 5, price: 2.5 } ]
}
返回每个 Client 的总价
对orders
集合执行 map-reduce 操作以对cust_id
进行分组,并为每个cust_id
计算price
的总和:
-
定义 Map 功能来处理每个 Importing 文档:
-
在函数中,
this
表示正在执行 map-reduce 操作的文档。 -
该函数将每个文档的
price
Map 到cust_id
并发出cust_id
和price
对。
var mapFunction1 = function() {
emit(this.cust_id, this.price);
};
-
使用两个参数
keyCustId
和valuesPrices
定义相应的 reduce 函数: -
valuesPrices
是一个数组,其元素是 map 函数发出的price
值,并按keyCustId
分组。 -
该函数将
valuesPrice
数组减少为其元素的总和。
var reduceFunction1 = function(keyCustId, valuesPrices) {
return Array.sum(valuesPrices);
};
- 使用
mapFunction1
map 函数和reduceFunction1
reduce 函数对orders
集合中的所有文档执行 map-reduce。
db.orders.mapReduce(
mapFunction1,
reduceFunction1,
{ out: "map_reduce_example" }
)
此操作将结果输出到名为map_reduce_example
的集合。如果map_reduce_example
集合已经存在,则该操作将使用此 map-reduce 操作的结果替换内容:
计算订单和总数量以及每件商品的平均数量
在此示例中,您将对orders
集合上所有ord_date
值大于01/01/2012
的文档执行 map-reduce 操作。工序按item.sku
字段分组,并计算每个sku
的订单数量和总 Order 量。通过计算每个sku
值的每个订单的平均数量来结束该操作:
-
定义 Map 功能来处理每个 Importing 文档:
-
在函数中,
this
表示正在执行 map-reduce 操作的文档。 -
对于每个项目,该函数将
sku
与新对象value
关联,该对象包含1
的count
和订单的项目qty
并发出sku
和value
对。
var mapFunction2 = function() {
for (var idx = 0; idx < this.items.length; idx++) {
var key = this.items[idx].sku;
var value = {
count: 1,
qty: this.items[idx].qty
};
emit(key, value);
}
};
-
使用两个参数
keySKU
和countObjVals
定义相应的 reduce 函数: -
countObjVals
是一个数组,其元素是 Map 到由 map 函数传递给 reducer 函数的分组的keySKU
值的对象。 -
该函数将
countObjVals
数组简化为包含count
和qty
字段的单个对象reducedValue
。 -
在
reducedVal
中,count
字段包含单个数组元素中count
字段的总和,qty
字段包含单个数组元素中qty
字段的总和。
var reduceFunction2 = function(keySKU, countObjVals) {
reducedVal = { count: 0, qty: 0 };
for (var idx = 0; idx < countObjVals.length; idx++) {
reducedVal.count += countObjVals[idx].count;
reducedVal.qty += countObjVals[idx].qty;
}
return reducedVal;
};
- 用两个参数
key
和reducedVal
定义一个 finalize 函数。该函数修改reducedVal
对象以添加一个名为avg
的计算字段,并返回修改后的对象:
var finalizeFunction2 = function (key, reducedVal) {
reducedVal.avg = reducedVal.qty/reducedVal.count;
return reducedVal;
};
- 使用
mapFunction2
,reduceFunction2
和finalizeFunction2
函数对orders
集合执行 map-reduce 操作。
db.orders.mapReduce( mapFunction2,
reduceFunction2,
{
out: { merge: "map_reduce_example" },
query: { ord_date:
{ $gt: new Date('01/01/2012') }
},
finalize: finalizeFunction2
}
)
此操作使用query
字段仅选择ord_date
大于new Date(01/01/2012)
的那些文档。然后将结果输出到集合map_reduce_example
。如果map_reduce_example
集合已经存在,则该操作会将现有内容与该 map-reduce 操作的结果合并。