2012-10-05 20 views
0

您好所有我想要做的是让每个不同departmentType的计数:的MongoDB /猫鼬:不能把简单的MapReduce工作

fnMap = function() { 
    emit(this.departments.departmentType, {typeCount:1}); 
} 

fnReduce = function(key, values) { 
    var result = {typeCount: 0}; 
    values.forEach(function(value) { 
    result.typeCount += value.brandCount; 
    }); 

    return result;    
}; 


var command = { 
mapreduce : "clients", 
query  : {"departments.departmentType": {$exists: true}}, 
map  : fnMap.toString(), 
reduce : fnReduce.toString(),  
    //sort: {"departments.departmentType":1}, 
    out: {inline: 1} 
}; 

mongoose.connection.db.executeDbCommand(command, function(err, dbres) { 

    }); 

当执行命令,dbres.documents [0 ] .results仅包含1个包含部门类型总数的项目,而不是每个部门类型的项目数量及其数量。

任何想法我做错了什么?

另外,当我取消注释SORT行时,出现错误“db assertion failure:could not create cursor over ...”,我相信字段名称是正确写入的。

+0

什么是brandCount减少?看起来像一个错字。应该是typeCount –

+0

我会添加更正mapReduce到我的答案,以防它有用,但你不需要mapReduce在这里。 –

回答

5

Mongoose v3现在有一个Model.mapreduce()函数(see doc)

显示的完整的例子是:

var o = {}; 
o.map = function() { emit(this.name, 1) } 
o.reduce = function (k, vals) { return vals.length } 
o.out = { replace: 'createdCollectionNameForResults' } 
o.verbose = true; 
User.mapReduce(o, function (err, model, stats) { 
    console.log('map reduce took %d ms', stats.processtime) 
    model.find().where('value').gt(10).exec(function (err, docs) { 
    console.log(docs); 
    }); 
}) 

以计数的问题,我相信是因为在你的fnReduce()函数你是峰会的结果,而不是在一个阵列显示它们。

+0

嗨,谢谢你的回应,但我不知道你的意思是什么“在你的fnReduce()函数中,你将登顶结果而不是将它们显示在一个数组中。”你能不能让我知道它应该如何? 我检查了Mongoose 3的语法,但我认为如果问题与我的reduce函数有关,我会遇到同样的问题。 谢谢 –

+0

嗨,我已经取得了一些进展,但还没有工作:在我之前的例子中,如果我“发射”类似this.field1的东西,它可以按照field1的所有不同值进行分组。但是,比第一级更深的任何字段都会失败:this.field1.field1a失败。任何想法为什么? –

+0

我试图在shell中运行这个(不带猫鼬)​​,你能否更新你的问题与集合的一些示例数据? –

0

您可以使用:

db.clients.distinct("departments.departmentType") 

这将会给所有的不同departmentType值的数组。

您的地图/缩小有两个问题。一个是brandCount减少而不是typeCount。但更重要的是,当您需要为每个部门数组元素发射一次时,您正试图为每个文档发射一次。更正(和稍微简化)的代码:

> fnMap = function() { 
    this.departments.forEach(
     function (d) { 
      emit(d.departmentType, 1); 
     } 
    ); 
} 
> fnReduce = function (key, values) { 
    var result = 0; 
    values.forEach(
     function (value) {result += value;}); 
    return result; 
} 
+0

感谢您的提示,感谢他们,我取得了一些进展。当我设置 'out:“NewCollection”' 它成功创建集合。 不过我想运行它 出来:{在线:1} 当我这样做,我则尝试使用的结果是这样的: mongoose.connection.db.executeDbCommand(命令,函数(错了,dbres){ \t dbres.find({ “值”:{$ GTE:5}})EXEC(函数(ERR,部门){\t \t ... \t \t \t \t}); 然而,我得到的find()不是一个有效的方法。这是正确的方式吗? 对不起,跳转所有e可能的解决方案,我正在尝试所有这些解决方案,但迄今为止没有运气 谢谢。 –

+0

为什么没有运气?只需使用不同的 - 你不需要map/reduce,除非你需要计数(然后使用聚合框架更容易)。如果你想内联的结果,那么他们不在任何集合,所以你不需要找到。内联将返回一个包含结果文档的数组“result”的文档。 –