一、使用MongoDB自带shell完成MapReduce。
1、首先插入测试数据。
use test
db.mapreduce.insert({"_id":"1","x":["a","b"]})
db.mapreduce.insert({"_id":"2","x":["b","c"]})
db.mapreduce.insert({"_id":"3","x":["c","d"]})
使用test数据库,在mapreduce collection的表中插入3条数据
使用
db.mapreduce.find()
查看数据中数据。如果有MongoVue也可以使用工具查看,
2、编写Map函数和Reduce函数
Map函数:
var m = function(){
for(var i = 0; i < this.x.length; i++){
emit(this.x[i],1);
}
}
Map函数调用emit(key,value)遍历collection中所有记录,将key与value传递给Reduce函数进行处理。使用this访问当前处理的document。
Reduce函数:
var r = function(key,values){
var sum = 0;
for(var i = 0; i < values.length; i++)
sum += values[i];
return sum;
}
Reduce函数接受的参数类似Group效果,将Map返回的键值序列组合成{key:[value1,value2,value...]}传递给reduce,在本例中组成{a:[1],b:[1,1],c:[1,1],d:[1]}
3、通过db.runCommand来执行MapReduce操作:
var res = db.runCommand({
mapreduce:"mapreduce",
map:m, reduce:r,
out:"mapreduce_out"});
mapreduce参数传入对应的collection名,map参数传入Map函数,out为输出的collection名,会在数据库中另外建一张表来保存处理后的结果。这是几个最基本的参数,还有更多参数可以查看Mongo实战,在我资源中有。也可以自己去网上找找。
最后的结果是:
{ "_id" : "a", "value" : 1 }
{ "_id" : "b", "value" : 2 }
{ "_id" : "c", "value" : 2 }
{ "_id" : "d", "value" : 1 }
可以通过
db.mapreduce_out.find()
查看。
二、使用spring-data-mongodb进行MapReduce
spring-data-mongodb是Apache公司方便javaer操纵mongodb的包。英文文档在我的资源中也有。基本的思想就是拿到MongoTemplete句柄,然后对mongodb进行操作。
1、存入测试数据,可以用shell直接存入,也可以用java代码。
2、定义一个实体类去存贮
public class ValueObject {
private String id;
private float value;
public String getId() {
return id;
}
public float getValue(){
return value;
}
public void setValue(float value) {
this.value = value;
}
}
3、Mapreduce
其实关键代码就一行:
package mongo_repository.mongo_repository;
import java.net.UnknownHostException;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import com.mongodb.Mongo;
public class MapReduce {
public static void main(String[] args) throws UnknownHostException {
MongoOperations mongoOperation = new MongoTemplate(new Mongo("localhost"), "test");
String map = "function () {for(var i=0;i<this.x.length;i++){emit(this.x[i],1);}}";
String reduce = "function(key, values){ var sum = 0; for(var i = 0; i<values.length;i++ )sum += values[i]; return sum; }";
//参数分别为:collection名,map函数的字符串,reduce函数的字符串,输出的表名[可选],实体类
MapReduceResults<ValueObject> results = mongoOperation.mapReduce("mapreduce", map, reduce,new MapReduceOptions().outputCollection("mr_out"), ValueObject.class);
}
}
暂时做一个这么简单的例子,其实mapreduce还可以做更复杂的功能,更详细的参数设定可以去看官方文档。