Map-Reduce 示例
在本页面
在mongo shell 中,db.collection.mapReduce()方法是MapReduce命令周围的 wrapper。以下示例使用db.collection.mapReduce()方法:
聚合管道作为替代
聚合管道 比map-reduce提供更好的性能和更一致的接口。
各种map-reduce表达式可以使用被重写聚合管道运算符,诸如
$group,$merge等下面的示例包括聚合管道备选方案。
orders使用以下文档创建样本集合:
db.orders.insertMany([
{ _id: 1, cust_id: "Ant O. Knee", ord_date: new Date("2020-03-01"), price: 25, items: [ { sku: "oranges", qty: 5, price: 2.5 }, { sku: "apples", qty: 5, price: 2.5 } ], status: "A" },
{ _id: 2, cust_id: "Ant O. Knee", ord_date: new Date("2020-03-08"), price: 70, items: [ { sku: "oranges", qty: 8, price: 2.5 }, { sku: "chocolates", qty: 5, price: 10 } ], status: "A" },
{ _id: 3, cust_id: "Busby Bee", ord_date: new Date("2020-03-08"), price: 50, items: [ { sku: "oranges", qty: 10, price: 2.5 }, { sku: "pears", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 4, cust_id: "Busby Bee", ord_date: new Date("2020-03-18"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 5, cust_id: "Busby Bee", ord_date: new Date("2020-03-19"), price: 50, items: [ { sku: "chocolates", qty: 5, price: 10 } ], status: "A"},
{ _id: 6, cust_id: "Cam Elot", ord_date: new Date("2020-03-19"), price: 35, items: [ { sku: "carrots", qty: 10, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 7, cust_id: "Cam Elot", ord_date: new Date("2020-03-20"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 8, cust_id: "Don Quis", ord_date: new Date("2020-03-20"), price: 75, items: [ { sku: "chocolates", qty: 5, price: 10 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 9, cust_id: "Don Quis", ord_date: new Date("2020-03-20"), price: 55, items: [ { sku: "carrots", qty: 5, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 }, { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 10, cust_id: "Don Quis", ord_date: new Date("2020-03-23"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }
])返回每位客户的总价格
对orders集合执行map-reduce操作,以对进行分组cust_id,并计算price每个的 的总和cust_id:
定义map函数来处理每个输入文档:
在函数中,
this指的是map-reduce操作正在处理的文档。该函数将映射
price到cust_id每个文档的,并发出cust_id和price对。
使用两个参数
keyCustId和定义相应的reduce函数valuesPrices:valuesPrices是一个数组,其元素是price由map功能发射并由分组值keyCustId。该函数将
valuesPrice数组简化为其元素的总和。
orders使用mapFunction1map函数和reduceFunction1reduce函数对集合中的所有文档执行map-reduce 。
此操作将结果输出到名为的集合 map_reduce_example。如果map_reduce_example集合已经存在,则该操作将用此map-reduce操作的结果替换内容。
查询
map_reduce_example集合以验证结果:
该操作返回以下文档:
聚合替代
使用可用的聚合管道运算符,您可以重写map-reduce操作,而无需定义自定义函数:
$group由平台组cust_id并计算value字段(参见$sum)。该value字段包含price每个的总计cust_id。该阶段将以下文档输出到下一阶段:
查询
agg_alternative_1集合以验证结果:该操作返回以下文档:
用每个项目的平均数量计算订单和总数量
在此示例中,您将对值大于或等于的orders所有文档在集合上执行map-reduce操作 。工序按字段分组 ,并计算每个的订单数量和总订购量。然后,该操作将为每个值计算每个订单的平均数量,并将结果合并到输出集合中。合并结果时,如果现有文档的密钥与新结果相同,则该操作将覆盖现有文档。如果不存在具有相同密钥的文档,则该操作将插入该文档。
定义map函数来处理每个输入文档:
在函数中,
this指的是map-reduce操作正在处理的文档。对于每个商品,该函数将其
sku与一个新对象相关联,该对象value包含订单的countof1和该商品qty,并发出skuandvalue对。
使用两个参数
keySKU和定义相应的reduce函数countObjVals:countObjVals是一个数组,其元素是映射到keySKU由map函数传递给reducer函数的分组值的对象。该函数将
countObjVals数组简化为reducedValue包含count和qty字段的单个对象。在中
reducedVal,该count字段包含count各个数组元素的qty字段总和,而该字段包含各个数组元素的 字段总和qty。
定义有两个参数的函数确定
key和reducedVal。该函数修改reducedVal对象以添加一个名为avg的计算字段,并返回修改后的对象:在执行的map-reduce操作
orders使用集合mapFunction2,reduceFunction2和finalizeFunction2功能。此操作使用该
query字段选择仅ord_date大于或等于的那些文档。然后将结果输出到集合 。new Date("2020-03-01")map_reduce_example2如果
map_reduce_example2集合已经存在,则该操作会将现有内容与此map-reduce操作的结果合并。也就是说,如果现有文档具有与新结果相同的密钥,则该操作将覆盖现有文档。如果不存在具有相同密钥的文档,则该操作将插入该文档。查询
map_reduce_example2集合以验证结果:该操作返回以下文档:
聚合替代
使用可用的聚合管道运算符,您可以重写map-reduce操作,而无需定义自定义函数:
该
$match阶段仅选择ord_date大于或等于new Date("2020-03-01")的那些文档。该
$unwinds阶段按items数组字段细分文档,以输出每个数组元素的文档。例如:$group由平台组items.sku,计算每个SKU:该
qty字段。该qty字段包含qty每个订单的总数items.sku(请参阅参考资料$sum)。orders_ids列表。该orders_ids字段包含不同顺序的列表_id的对items.sku(参见$addToSet)。
最后,
$merge将输出写入collectionagg_alternative_3。如果现有文档的密钥_id与新结果相同,则该操作将覆盖现有文档。如果不存在具有相同密钥的文档,则该操作将插入该文档。查询
agg_alternative_3集合以验证结果:该操作返回以下文档:
译者:李冠飞
校对:
最后更新于