MongoDB文档翻译-Map Reduce示例

英文原文地址:https://docs.mongodb.com/v3.2/tutorial/map-reduce-examples/
本文章属个人翻译,作个人学习之用,如有雷同,纯属巧合。如有错误之处,欢迎指正。

Map-Reduce示例

mongoshell中,db.collection.mapReduc()方法是对命令mapReduce的封装。以下例子使用db.collection.mapReduce()方法。

考虑以下对集合order的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 } ]
}

返回每个客户的总价格

orders集合执行map-reduce操作,按cust_id分组,计算每个cust_idprice的总和:

  1. 定义map函数来处理每个输入文档:

    • 在函数中this引用的是map-reduce操作处理中的文档。
    • 该函数对每个文档把price映射到cust_id,然后产生cust_id与price对。
    var mapFunction1 = function() {
                           emit(this.cust_id, this.price);
                       };
  2. 定义相应的reduce函数,有连个参数,keyCustId和valuesPrices:

    • valuesPrice是一个数组,其元素是由map函数按keyCustId分组的price值。
    • 该函数对valuesPrice数据归约成其元素之和。
    var reduceFunction1 = function(keyCustId, valuesPrices) {
                              return Array.sum(valuesPrices);
                          };
  3. orders集合中的所有文档执行map-reduce操作,用mapFunction1作为map函数,reduceFunction1作为reduce函数。

    db.orders.mapReduce(
                         mapFunction1,
                         reduceFunction1,
                         { out: "map_reduce_example" }
                       )

    该操作把结果输出到名为map_reduce_example的集合。如果该集合已经存在,该操作会用map-reduce的结果替换掉该集合的内容。

    计算每个商品的订单和总数量、平均数量

    该例子中,你将对orders集合中ord_date值大于01/01/2012的所有文档进行map-reduce操作。该操作对item.sku字段分组,计算每个sku的订单数和订单总量。该操作最后计算每个`sku的平均订单数量。

    1. 定义处理每个输入文档的map函数:

      • 在函数中this引用的是map-reduce操作处理中的文档。
      • 对于每个商品,该函数用一个新的对象value来关联sku,该对象的count是1,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);
                             }
                          };
    2. 定义相应的reduce函数,它有两个参数,keySKU和countObjVals:

      • countObjVals是一个数组,它的元素被映射到分组的keySKU,是通过map函数传过来的。
      • 该函数把countObjVals归约到单个reducedValue对象,该对象包含count和qty字段。
      • 在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;
                        };
    3. 定义一个终止函数,有两个参数,key和reducedVal。该函数修改reducedVal对象,添加了一个叫做avg的计算字段,并且返回修改后的对象。

      var finalizeFunction2 = function (key, reducedVal) {
      
                             reducedVal.avg = reducedVal.qty/reducedVal.count;
      
                             return reducedVal;
      
                          };
    4. mapFunction2reduceFunction2finalizeFunction2函数对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的结果与已经存在的内容合并。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值