先看下mongodb官方给出的例子的图。
个人理解的解释:
这个图,有四列数据。
第一列:原始数据。通常对应的mongodb里面的一个表collection。
第二列:经过某些条件过滤过的数据,这个图里面就是按{"status":"A"}过滤数据。这个过滤的条件对应上面代码里面query后面的
第三列:就是经过reduce操作之后的结果。其中的key,对应为reduce方法的参数的key,这个key来自于map函数,map函数,就是负责返回一个key value的数据结构。这个图里面就是以“cust_id”的值,当key,然后以“amount”字段的值当values,注意这地方是values,不是value。这个就是这个map函数的作用,他把key去重,然后,要是相同的key对应的value就会被放到这个values里面来,准备给reduce函数使用。
第四列:就是整个语句的执行结果啦。使用map和reduce函数,最终获得结果。这个结果和reduce函数相关。这个图里面,他就是把map函数得到的key 的values求和。然后key经过去重之后,就剩下2个,然后最后的结果就产生2条数据,在mongodb里面叫document。这2个document组成了一个新的表,mongodb管表叫collection。这个表的名字是由代码里面的out字段负责对应设置的。
经过这么一波简单的个人通俗的语言说明之后,就可以大致了解到这个mongodb的map reduce的大概作用啦。
简单总结一下上面这个图的意思:假设字段cust_id代码用户,amount代表金额。那么他整体就是算符合条件(status==A)的每一个用户的总金额是多少。
然后,根据他这个例子,咱自己也再走一个试试。具体继续看。。。
先是mongo语句:
var map = function () {
var key = this.region;
var value = {
latitude: this.latitude
};
emit(key, value);
};
var reduce = function (key, values) {
var result = {
region: key,
totalLatitude: 0
};
values.forEach(function (value) {
result.totalLatitude += value.latitude;
});
return result;
};
db.geos.mapReduce(
map,
reduce,
{
out: "newCollection"
}
)
然后,我是在romongo里面执行这个语句的。下面是执行的结果。有点长。
/* 1 */
{
"result" : "newCollection",
"timeMillis" : 1196.0,
"counts" : {
"input" : 3239,
"emit" : 3239,
"reduce" : 63,
"output" : 34
},
"ok" : 1.0,
"_o" : {
"result" : "newCollection",
"timeMillis" : 1196,
"counts" : {
"input" : 3239,
"emit" : 3239,
"reduce" : 63,
"output" : 34
},
"ok" : 1.0
},
"_keys" : [
"result",
"timeMillis",
"counts",
"ok"
],
"_db" : {
"_mongo" : {
"slaveOk" : true,
"host" : "192.168.1.161:27017",
"defaultDB" : "ezsonar_25",
"authStatus" : {
"authRequired" : true,
"isMaster" : true,
"replSetGetStatus" : true
},
"_readMode" : "commands"
},
"_name" : "ezsonar_25"
},
"_coll" : {
"_mongo" : {
"slaveOk" : true,
"host" : "192.168.1.161:27017",
"defaultDB" : "ezsonar_25",
"authStatus" : {
"authRequired" : true,
"isMaster" : true,
"replSetGetStatus" : true
},
"_readMode" : "commands"
},
"_db" : {
"_mongo" : {
"slaveOk" : true,
"host" : "192.168.1.161:27017",
"defaultDB" : "ezsonar_25",
"authStatus" : {
"authRequired" : true,
"isMaster" : true,
"replSetGetStatus" : true
},
"_readMode" : "commands"
},
"_name" : "ezsonar_25"
},
"_shortName" : "newCollection",
"_fullName" : "ezsonar_25.newCollection"
}
}
我使用的这个对应的model,或者叫表,或者叫collection
然后,对我这个例子map reduce进行下解释:
map,就是按region区域,来统计每个区域的latitude的值,这个经纬度的值。同一个region的数据document有很多,然后map函数就是把同一个region的latitude全部统计到value里面去,我在map里面是使用一个js对象来接受的,到时候在reduce里面取的时候,还的以对象的形式取出来。代码里面的this,就是指当前的某一个document,
reduce,就是计算一下某个region这个key对应的所有的values的经纬度的total值。
最后out到一个新的collection。数据结构具体如下:
生成了34条,可以看下上面的这个map reduce函数的执行结果里面也是有这个34的
我写完文章,给自己点个赞,不过分吧,
不过分,那我可就点啦啊。
我先点为敬,你们随意。大家随意。不要客气。。。