MapReduce是面向大数据并行处理的计算模型。MongoDb中提供了MapReduce的聚合工具,来实现任意复杂的逻辑,很强大,很灵活。它的计算理念是:将一个大问题拆分成若干个小问题,将各个小问题发送到不同的机器上进行计算。在各个小问题解决完时,再将这些小问题的结果合并为一个最终的结果。
从设计理念可以看出,MapReduce操作有2个阶段:第一个阶段是Map(映射)阶段,第二个阶段是Reduce(化简)阶段。可以参考官网的一个demo:
- 先查找符合条件的数据:查找出order集合中所有status为A的记录。
- 然后执行Map(映射):根据order集合记录中cust_id字段为key,amount为value进行规约。所有相同的key的所有value,组成一个数组,传给后面的reduce。
- 最后进行Reduce(化简):是把由map传回来的key/value的value进行求和,得到最终以每个用户(cust_id)为key,所有金额求和的值为value的结果。最终结果out在临时表“order_totals”中。
附上我用java写的一段MapReduce代码:
/**
* 查询订单表中的积分
*
* @return 积分数
*/
public int selectOrderInfoScore(Query query) {
String mapStr = "function() { emit(this.pay_type, { \"score\": this.score }) }";
String reduce = "function(key, values) {\n" +
" var scores = 0;\n" +
" for (var i in values) {\n" +
" scores += values[i].score;\n" +
" }\n" +
" return { \"score\": scores };\n" +
" }";
MapReduceResults<LinkedHashMap> reduceResults = mongoOperations.mapReduce(query, "order_info", mapStr, reduce, LinkedHashMap.class);
Double score = 0D;
for (LinkedHashMap map : reduceResults) {
Map map2 = (Map) map.get("value");
score += (Double) map2.get("score");
}
return score.intValue();
}
reduce函数中return的值需要跟map函数中key的数据结构一致。