初次試用了一下mongodb的mapreduce方法镣煮,總結(jié)了一些粗淺的認(rèn)識(shí)埃跷,記錄如下:
下面例子中金度,document保存的是每次http請(qǐng)求的信息本讥,time域?yàn)檎?qǐng)求的時(shí)間珊泳,method域?yàn)檎?qǐng)求的方法(比如GET,POST)拷沸。
map方法:
- 遍歷collection中的所有document旨椒,按照map方法中定義的規(guī)則,對(duì)這些document進(jìn)行分組堵漱。
//這里把time域中相同小時(shí)的document分到一組
//this為遍歷時(shí)的某個(gè)具體的document
var key = this.time.getHours();
- 根據(jù)需求综慎,抽取value值,作為reduce方法的輸入勤庐。
var value = 0;
//如果method域的內(nèi)容為GET時(shí)示惊,設(shè)置value為1好港,否則為0。
//這里的value是簡單的數(shù)值類型米罚,也可能是稍微附在的對(duì)象卤材。
if(this.method=='GET'){
value = 1;
}
- emit key value狸窘,供reduce處理橡娄。
emit(key, value);
reduce方法:
相同的key值會(huì)傳給同一個(gè)reduce方法來處理立美,reduce有2個(gè)輸入?yún)?shù):key和values。其中:values為map方法emit出的相同key值對(duì)應(yīng)的value的集合隘竭。下面的例子把所有的value值做一個(gè)加和處理
reduce = function(key, values){
var sum = 0;
values.forEach(function(value){
sum += value;
});
return sum;
}
上面的的mapreduce就能夠計(jì)算出collection中塘秦,一天中每小時(shí)時(shí)間段內(nèi)GET
請(qǐng)求的次數(shù)。
具體java代碼如下:
String map = String.format("function() {\n" +
" var key = this.time.getHours();\n" +
" var value = 0;\n" +
" if(this.method==\'GET\'){value=1;}\n" +
" emit(key, value);\n" +
"}";
String reduce = "function(key, values){\n" +
" var sum = 0;\n" +
" values.forEach(function(value){\n" +
" sum += value;\n" +
" });\n" +
" return sum;\n" +
"}";
MapReduceResults<ValueObject> results = mongoOperations.mapReduce(
PlatformAccessLog.COLLECTION_NAME, map, reduce, ValueObject.class);