我正在尝试对mongodb 2.0.1中每个组的元素数量进行分组和计算,但到目前为止还没有成功。
我的数据库架构如下:
{
"_id" : ObjectId("4ece7544853b4b0941000000"),
"ResultSet" : {
"Results" : [
{
"quality" : 87,
"state" : "Franche-Comté"
}
]
}
}
我一直在尝试所有类型的方法,遵循不同的教程,但每次都是相同的结果:只有一个空组...我不明白为什么。
我到目前为止所写的最佳查询如下:
db.extract_2000.group( {
cond: { "ResultSet.Results.quality": {$exists: true} },
key: {"ResultSet.Results.state": true},
reduce: function(obj, glob) { glob.total++; glob.quality += obj.ResultSet.Results.quality },
initial: { total: 0, quality: 0 },
finalize: function(glob) {glob.avgquality = glob.quality / glob.total}
})
返回(再次):
[
{
"ResultSet.Results.state" : null,
"total" : 2000,
"quality" : NaN,
"avgquality" : NaN
}
]
我做错了什么?
答案 0 :(得分:2)
这根本不会像书面那样工作。关键问题在于:key: {"ResultSet.Results.state": true}
。 ResultSet.Results
是一个数组。当您要求ResultSet.Results.state
时,您暗示要在此处执行某种类型的for
循环。 group
命令根本无法做到这一点。
请尝试以下M / R:
map = function() {
// Note that we emit once per result
foreach(var i in ResultSet.Results) {
key = this.ResultSet.Results[i];
value = { count: 1,
quality: this.ResultSet.Results[i].quality,
avg_quality: 0
};
emit(key, value);
}
}
reduce = function(key, values) {
// note that results has same fields as emitted value
var results = { count: 0, quality: 0, avg_quality: 0 };
foreach(var i in values){
results.count += values[i].count;
results.quality += values[i].quality;
// ignore avg_quality, we don't use it
}
return results;
}
您还必须为平均值写一个finalize
。
finalize = function(key, value) {
if (value.count > 0)
value.avg_quality = value.quality / value.count;
return value;
}
答案 1 :(得分:0)
地图功能
map = function() {
for(var i in this.Results) {
emit(this.Results[i].state,
{quality: this.Results[i].quality, total: 1, avgquality: 0}
);
}
}
减少功能
reduce = function(key, values) {
var data = {quality: 0, total: 0, avgquality: 0};
for(var i=0; i<values.length; i++) {
data.quality += values[i].quality;
data.total += values[i].total;
}
return data;
}
在finalize函数中只计算平均值