使用mongoose中的mapReduce方法统计结果。
示例,以审方订单中药师为key进行统计,统计出每个药师的审方订单数量。
var o = {};
// `map()` and `reduce()` are run on the MongoDB server, not Node.js,
// these functions are converted to strings
o.query = {pharmacist: {$nin:[null]}};
o.map = function () { emit(this.pharmacist, 1) };
o.reduce = function (k, vals) { return Array.sum(vals); };
// o.sort = {value: -1}; 不起作用,不能按照value排序,原因待查
Order.mapReduce(o, function (err, analysis) {
if (err) {
return next(err);
} else {
console.info(analysis);
}
})
为了能够对结果进行排序,改为下列写法
var o = {};
// You can also define `map()` and `reduce()` as strings if your
// linter complains about `emit()` not being defined
o.query = {pharmacist: {$nin:[null]}};
o.map = function () { emit(this.pharmacist, 1) };
o.reduce = function (k, vals) { return Array.sum(vals); };
o.out = { replace: 'dashboardResults' } // 会创建dashboardResults表,存储查询出来的数据
// o.verbose = true;
Order.mapReduce(o, function (err, model) {
// console.log('map reduce took %d ms', stats.processtime)
model.find().sort({'value': -1}).limit(3).exec(function (err, docs) {
console.log(docs);
});
})
排序后的结果如下
[ { _id: 5be13e0cbda19430fc9e5b1f, value: 3 },
{ _id: 5bd6aca5ab920a4360b9206d, value: 1 },
{ _id: 5be904255b450d6f20d74fc3, value: 1 } ]
文档链接:
https://mongoosejs.com/docs/api.html#model_Model.mapReduce添加链接描述
说明:
创建map函数
var m = function() {
emit(this.age, this.name);
}
emit:返回一个键值对。emit的第一个参数是key,就是分组的依据,这是自然是age了,后一个是value,可以是要统计的数据,下面会说明,value可以是JSON对象。
这样m就会把送过来的数据根据key分组了,可以想象成如下结构:
第一组
{key:0,values: ["name_6","name_12","name_18"]
第二组
{key:1,values: ["name_1","name_7","name_13","name_19"]
......
第二步就是简化了,编写reduce函数
var r=function(key,values){
var ret={age:key,names:values};
return ret;
}
reduce函数会处理每一个分组,参数也正好是我们想像分组里的key和values。