我用NodeJs写了一段代码,如下:
其中的_id就是对应的上面写的map中的key也就是age字段,
从统计结果可以看出gender为man的记录中age为20的有两个,age为23的有1个。
参数说明:
使用out参数时要注意当使用inline时文档的数据不能太大,否则返回结果将出现错误,官网说明如下:
如果verbose:true的时候callback返回中多一个stats字段:
返回结果参数如下:
- result:储存结果的collection的名字
- input:满足条件的数据行数
- emit:emit调用次数,也就是所有集合中的数据总量
- ouput:返回结果条数
- timeMillis:执行时间,毫秒为单位
- ok:是否成功,成功为1
- err:如果失败,这里可以有失败原因,原因一般比较模糊,作用不大
使用scope参数我们可以在map、reduce、finalize中引入外界函数或变量:
参考官网教程:mapReduce
![在NodeJs中使用MongoDB中的MapReduce 在NodeJs中使用MongoDB中的MapReduce](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
注意:我在使用中发现当我们map中的value为单个字符,而reduce返回的为json的时候会出现异常,且reduce中的value值中字段的数目不相等也会出现异常。所以:
如上图中的情况,得到的结果将出现异常
我先往数据库插入一些数据:health/routes/add.js
数据结构是这样的:
{"name":"张三","age":58,"gender":"男","birthday":"1905-12-09","mobile":"15815222297","note":"北京"}
我们现在来统计下刚刚插入的数据的姓名中一共有多少个姓,每个姓有多少人
所以统计的结构应该是这样的:key就是姓,然后value中是统计的人数
先写map函数:(在map中我们取出每个collections名字中的姓)
var map = function () {
vara=this.name.substring(0,1);
emit(a, {count:1}); //map时姓相同的为一组传给reduce,传的值中key为name中的姓
};
然后再写一个reduce处理函数:(统计每个姓的人数)
var reduce = function (key, values) {
var x = 0;
values.forEach(function (v){
x += v.count;
});
return{count:x};//统计出每个姓一共有多少人
};
然后我们用finalize函数根据统计的结果給每个姓写一个comment:
functionfinalize(key,rval){
returncomment(rval);
}
其中comment函数是我从外界引入的所以需要在scope中申明一下
function comment(input){
if(input.count>100){
input.comment="该姓人数较多!"
}
return input;
}
然后开始执行统计函数:
testProvider.mapReduce(map, reduce, {out:{replace:'tempCollection'},
scope:{comment:newCode(comment.toString())},
finalize:finalize,verbose:true},
function (err,collection, stats) {})
然后得出统计结果和统计时的资源使用情况:
![](https://img-my.csdn.net/uploads/201301/05/1357365692_7642.png)
![](https://img-my.csdn.net/uploads/201301/05/1357365697_4557.png)