0、说明
官方给的Map-Reduce的流程如下图:
该函数接收三个参数:map
,reduce
,{query
,output
};其中map
,reduce
是方法,最后一个参数是对象,
该对象可以使用query
作为查询过滤条件,output
的意思是将结果保存在临时的集合里边,最后用来查询。
首先,数据库我存的订餐数据如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| { "_id" : ObjectId("56b45c45ad1434e863ea1406"), "user_id" : ObjectId("568bbaa0e78f752802a65a7b"), "dish_name" : "韭菜鸡蛋", "deleted" : false, "update_at" : ISODate("2016-02-05T08:24:37.761Z"), "create_at" : ISODate("2016-02-05T08:24:37.761Z"), "ispack" : false, "dish_price" : 12, "__v" : 0 } { "_id" : ObjectId("56b45c5fad1434e863ea1407"), "user_id" : ObjectId("568bbaa0e78f752802a65a7b"), "dish_name" : "红烧鸡块", "deleted" : false, "update_at" : ISODate("2016-02-05T08:25:03.070Z"), "create_at" : ISODate("2016-02-05T08:25:03.070Z"), "ispack" : false, "dish_price" : 15, "__v" : 0 } { "_id" : ObjectId("56b45c66ad1434e863ea1408"), "user_id" : ObjectId("568bbaa0e78f752802a65a7b"), "dish_name" : "耗油生菜", "deleted" : false, "update_at" : ISODate("2016-02-05T08:25:10.002Z"), "create_at" : ISODate("2016-02-05T08:25:10.002Z"), "ispack" : false, "dish_price" : 13, "__v" : 0 }
|
下边会介绍对这些数据进行查询统计!
1、map方法
先看代码:
1 2 3 4
| var map=function(){ var cate=this.dish_name; emit(cate,{price:this.dish_price}); }
|
map方法里面会调用emit(key, value)
,mongodb集合会按照指定的key
进行映射分组, 类似关系型数据库的group by
,
目的是group by
上面map后的结果,最终为:按照cate分组, 分组结果是{name: this.name}的list。
2、reduce方法
(遍历map的结果,统计订单中每种盖饭的总数和总价格)
1 2 3 4 5 6 7 8 9
| var reduce=function(key,values){ var sum=0; var totalCost=0; values.forEach(function(order){ sum+=1 totalCost+=order.price; }); return {count:sum,cost:totalCost}; }
|
3、执行mapReduce方法
1 2
| db.orders.mapReduce(map,reduce,{out:"order_results"}); db.order_results.find();
|
查询结果如下,最终的集合里边,_id
就是cate
,value
就是统计的值了。
{ “_id” : “红烧鸡块”, “value” : { “count” : 2, “cost” : 30 } }
{ “_id” : “耗油生菜”, “value” : { “count” : 2, “cost” : 26 } }
统计示例见:订餐统计