db.collection.mapReduce(
function() {emit(key,value);}, //map 函数 生成键值对传递给reduce函数
function(key,values) {return reduceFunction}, //reduce 统计函数函数
{
out: collection, // 统计结果存放的集合
query: document,// 查询条件
sort: document,// 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
limit: number // 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)
}
)
db.getCollection('XXX_2019_04').mapReduce(
function(){ emit( {"baseMonitorMainId":this.baseMonitorMainId,"checkInDate":this.checkInDate,"bedType":this.bedType},
{"price":this.price,"max":this.max,"min":this.min,"avg":this.avg});},
function(key,values){
var price=values[0].price;var avg=values[0].price;
var max=values[0].price;var min=values[0].price;
values.forEach(function(val){
if(val.price>max ){
max=val.price;
}
if(val.price < min){
min = val.price
}
price=price+val.price
})
return {"price":price,"max":max,"min":min,"avg":avg}
},
{
out : "hotel_rate1",
}
)
MongoDB中使用emit函数向MapReduce提供Key/Value对。
Reduce函数接受两个参数:Key,emits. Key即为emit函数中的Key。 emits是一个数组,它的元素就是emit函数提供的Value。
Reduce函数的返回结果必须要能被Map或者Reduce重复使用,所以返回结果必须与emits中元素结构一致。
Map或者Reduce函数中的this关键字,代表当前被Mapping文档。
DBCollection roomRateDto = mongoTemplate.getCollection(param.get("collectionName").toString());
DBObject query = new BasicDBObject();
String map = CommonUtils.getPropertiesValue(PATH,"map_pre");
String reduce = CommonUtils.getPropertiesValue(PATH,"reduce_pre");
String collectionName=MongodbKeyConstants.HOTEL_RATES_PROCESS + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM"));
MapReduceCommand reduceCommand = new MapReduceCommand(roomRateDto, map, reduce, collectionName, OutputType.MERGE, query);
try{
roomRateDto.mapReduce(reduceCommand);
}catch (Exception e){
e.printStackTrace();
}
使用中的坑: 当emit()的分组如果一组的数据量比较大,那么该组的数据格式就是数组里面套数组,连续的套
所以要求在reduce 函数里面返回值的格式必须要reduce函数的参数values是一样的,官方文档也有明确的要求
,如果不一样极有可能会导致计算的结果是错误的.