MongoDB中的组和计数

MongoDB中的组和计数,mongodb,group-by,mapreduce,Mongodb,Group By,Mapreduce,我试图在mongodb 2.0.1中对每个组进行分组和计算元素的数量,但到目前为止没有成功 我的数据库模式如下所示: { "_id" : ObjectId("4ece7544853b4b0941000000"), "ResultSet" : { "Results" : [ { "quality" : 87,

我试图在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}
            })
返回(再次):


我做错了什么?

这根本不符合书面要求。关键问题在这里:
key:{“ResultSet.Results.state”:true}
<代码>结果集。结果是一个数组。当您要求
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 = function(key, value) {
  if (value.count > 0)
    value.avg_quality = value.quality / value.count;

  return value;
}
map函数

map = function() {

    for(var i in this.Results) {
        emit(this.Results[i].state, 
            {quality: this.Results[i].quality, total: 1, avgquality: 0}
        );
    }
}
reduce函数

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;
}
reduce=函数(键、值){
var数据={quality:0,total:0,avgquality:0};

对于(var i=0;我不确定您试图实现什么——不知何故,您试图对嵌入的文档而不是文档进行分组?我认为这行不通,而且就我所知,
$exists
条件不会适用于每个嵌入的文档。您是否尝试过使用简单对象而不是具有子对象数组的对象cts?是计数(
总计
)好的?总数还可以,我在数据库中有2000个文档。我尝试按ResultSet.Results.state对每个文档进行分组。好的,您有2000个文档,但这意味着您的reduce函数必须手动迭代子文档数组,不是吗?表达式
obj.ResultSet.Results.quality
不能在reduce函数中进行计算,我思考:
Results
是一个数组,但您使用它就像使用普通对象一样。我认为这是罪魁祸首。好的,非常感谢,我更了解我的问题。当我使用find()时,mongodb很好地管理了数组中键的搜索,我愚蠢地认为在reduce函数中也是如此。我尝试了一个更正,将reduce函数改为:function(obj,glob){glob.total++;glob.quality++=obj.ResultSet.Results[0].quality},并给出了结果。但我不知道(也不认为)如果我可以在关键参数中使用数组索引。我认为您不应该在您的案例中使用子文档。如果您将这些结果对象放在它们自己的集合中,并为每个项目使用单独的对象,您应该会更好。这也使映射/还原更容易。
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;
}