2015-12-31 114 views
1

我想获得每个地区的学生数量。 我有一个模式,看起来像mapReduce使用node.js和猫鼬

var mongoose = require('mongoose'); 
var schema = mongoose.Schema; 
var studentSchema = new mongoose.Schema(
{ 
"name":String, 
"address" :{ 
    "locality":String 
    } 
}); 
module.exports = mongoose.model('Student', studentSchema); 

我那么有一些Node.js的代码

var Student = require('../../../models/Student'); 
module.exports.getStudentsBasedOnLocality = function(){ 
var o = {}; 
o.map = function() { 
    emit(Student.address.locality, 1) 
} 
o.reduce = function (k, vals) { 
    return vals.length 
} 

Student.collection.mapReduce(o, function (err, results) { 
    if(err) throw err; 
    console.log(results) 
}) 
}; 

错误我得到的是。有关我可能做错什么的提示?

类型错误

Cannot read property 'out' of undefined 
at Collection.mapReduce (C:\***\node_modules\mongodb\lib\collection.js:2961:21) 
at NativeCollection.(anonymous function) [as mapReduce] (C:\***\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:136:28) 

回答

1

尝试直接调用模型上的mapReduce()方法,而不是需要一个额外的对象作为与出属性参数模型的集合属性:

var Student = require('../../../models/Student'); 
module.exports.getStudentsBasedOnLocality = function(){ 
    var o = {}, 
     self = this; 
    o.map = function() { 
     emit(this.address.locality, 1) 
    }; 
    o.reduce = function (k, vals) { 
     return vals.length 
    }; 

    Student.mapReduce(o, function (err, results) { 
     if(err) throw err; 
     console.log(results) 
    }); 
}; 

另一种替代方案是使用aggregation framework,其具有bett因为聚合在服务器本地运行(C++),而mapReduce衍生出单独的JavaScript线程来运行JavaScript代码。你可以这样运行以下程序aggregation pipeline来达到同样的效果:

var Student = require('../../../models/Student'); 
module.exports.getStudentsBasedOnLocality = function(){ 
    var pipeline = [ 
     { 
      "$group": { 
       "_id": "$address.locality", 
       "count": { "$sum": 1 } 
      } 
     } 
    ]; 

    Student.aggregate(pipeline, function (err, results) { 
     if(err) throw err; 
     console.log(results) 
    }); 
};