2012-10-05 27 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」的文檔。 –