mongodb中使用MapReduce
MapReduce函数的用法如下:
?db.users.mapReduce(map, reduce 另外,在使用 ./mongo登录到客户端上,map和reduce函数都不能被引号引起来,否则就是字符串,而不是函数了,这点就是纯粹的javascript 举个例子: 对于类似如下形式的collection(名为:example) > reduce=function(key,values){return {count:1}}"timeMillis" : 492, > db.temp.find() 注意:上边输出的结果,并没有变成reduce函数所返回的 {count:2} 值,而是返回了map中emit方法弹出的“1”。原因可能是因为对于某个key,如果他的值在符合条件的结果集合中如果只有一条数据,那么mapReduce函数将不会去调用reduce函数进行计算。另外,mapReduce函数返回的结果,其collection结构一般情况下会跟map函数中emit(key,value)方法中的value参数的结构保持一致的 而如果map和reduce函数换成如下形式,reduce函数将被调用: 如果想使用sort和limit等功能,可以使用 res.find().sort({"value.totalNum":-1}).limit(2)来达到目的 再补充一点使用java客户端连接mongodb,使用MapReduceOutput.getCollection().find()返回的结果中会以如下DBObject的形式出现:
{_id:4,type:'cat',num:1}
{_id:11,type:'dog',num:3}
{_id:34,type:'pig',num:1}
{_id:40,type:'cat',num:2}
> map=function(){emit(this._id,1)}
function () {
emit(this._id, 1);
}
"counts" : {
"input" : 12453,
"emit" : 12453,
"output" : 12076
},
"ok" : 1,
}
{ "_id" : 4, "value" : 1 }
{ "_id" : 11, "value" : 1 }
{ "_id" : 34, "value" : 1 }
{ "_id" : 40, "value" : 1 }
> res
{
"result" : "temp",
"timeMillis" : 492,
"counts" : {
"input" : 12453,
"emit" : 12453,
"output" : 12076
},
"ok" : 1,
}
> //也可以使用如下形式查询
> res.find()
{ "_id" : 4, "value" : 1 }
{ "_id" : 11, "value" : 1 }
{ "_id" : 34, "value" : 1 }
{ "_id" : 40, "value" : 1 }
>map=function(){
emit(this.type,{totalNum:this.num});
}
>reduce=function(key,values){
var totalNum=0;
values.forEach(function(val){
totalNum+=val
});?
return totalNum;
}
>res=db.example.mapReduce(map,reduce,{out:"temp"});
>res.find();
{_id:"cat",value:{totalNum:3}}
{_id:"dog",value:{totalNum:3}}
{_id:"pig",value:{totalNum:1}}
{_id:"cat",value:{totalNum:3}}
但如果你使用 DBObject object=MapReduceOutput.getCollection().find() ;//其中的MapReduceOutput应该为Collection.mapReduce()函数返回的对象,此处简便的写成这样,不要误会
System.out.println(object.get("value.totalNum")); //此处将打印出null
因为object.get("value")将返回一个Object,在这个对象没有强制转换成DBObject之前,它是不能简单的使用“.”操作符来获取值的,正确的做法如下:
DBObject value=(DBObject)object.get("value");
System.out.println(value.get("totalNum"));