MongoDB如何使用嵌套聚合计数


  • 註冊用戶

    我需要对统计页面的注册收集数据进行分组和计数,以及进行动态注册,但是我无法得到多于一个分组的数据。 样本注册收集数据:

    { "_id" : ObjectId("58ec60078cc818505fb75ace"), "event" : "Women's BB", "day" : "Saturday", "group" : "nonpro", "division" : "Women's", "level" : "BB" } { "_id" : ObjectId("58ec60078cc818505fb75acf"), "event" : "Coed BB", "day" : "Sunday", "group" : "nonpro", "division" : "Coed", "level" : "BB" } { "_id" : ObjectId("58ec60098cc818505fb75ad0"), "event" : "Men's BB", "day" : "Saturday", "group" : "nonpro", "division" : "Men's", "level" : "BB" } { "_id" : ObjectId("58ec60168cc818505fb75ad1"), "event" : "Men's B", "day" : "Saturday", "group" : "nonpro", "division" : "Men's", "level" : "B" } { "_id" : ObjectId("58ec60178cc818505fb75ad2"), "event" : "Women's Open", "day" : "Saturday", "group" : "pro", "division" : "Women's", "level" : "Pro" } { "_id" : ObjectId("58ec60188cc818505fb75ad3"), "event" : "Men's Open", "day" : "Saturday", "group" : "pro", "division" : "Men's", "level" : "Pro" } 

    我想重新组织它,并且可以返回类似的东西:

     [ {_id: { day: "Saturday", group: "nonpro" }, count: 3, divisions: [ { division: "Men's", count: 2, levels: [ { level: "BB", count: 1 }, { level: "B", count: 1 }] }, { division: "Women's", count: 1, levels: [ { level: "BB", count: 1 }] } }, {_id: { day: "Saturday", group: "pro" }, count: 2, divisions: [ { division: "Men's", count: 1, levels: [ { level: "Pro", count: 1 } }, { division: "Women's", count: 1, levels: [ { level: "Pro", count: 1 }] } }, {_id: { day: "Sunday", group: "nonpro" }, count: 1, divisions: [ { division: "Coed", count: 1, levels: [ { level: "BB", count: 1 } } }] 

    我知道应该使用aggregate()函数,但是不知道怎么让它和count一起使用。 这是我的总体看起来像这样:

     Registration .aggregate( { $group: { _id: { day: "$day", group: "$group" }, events: { $addToSet: { division: "$division", level: "$level"} }, total: { $sum: 1} } }) 

    这返回每天/组合组合的总注册数,但是如果我尝试添加总计:{$ sum:1}到事件集,我只需要获得1。 有没有办法在一个数据库调用中使这项工作,或者我需要分别为需要计数的每个分组级别进行分析?


  • Lv 1

    @sevengong

    db.c1.insertMany([{
        "_id": ObjectId("58ec60078cc818505fb75ace"),
        "event": "Women's BB",
        "day": "Saturday",
        "group": "nonpro",
        "division": "Women's",
        "level": "BB"
    } ,{
        "_id": ObjectId("58ec60078cc818505fb75acf"),
        "event": "Coed BB",
        "day": "Sunday",
        "group": "nonpro",
        "division": "Coed",
        "level": "BB"
    }, {
        "_id": ObjectId("58ec60098cc818505fb75ad0"),
        "event": "Men's BB",
        "day": "Saturday",
        "group": "nonpro",
        "division": "Men's",
        "level": "BB"
    } ,{
        "_id": ObjectId("58ec60168cc818505fb75ad1"),
        "event": "Men's B",
        "day": "Saturday",
        "group": "nonpro",
        "division": "Men's",
        "level": "B"
    }, {
        "_id": ObjectId("58ec60178cc818505fb75ad2"),
        "event": "Women's Open",
        "day": "Saturday",
        "group": "pro",
        "division": "Women's",
        "level": "Pro"
    }, {
        "_id": ObjectId("58ec60188cc818505fb75ad3"),
        "event": "Men's Open",
        "day": "Saturday",
        "group": "pro",
        "division": "Men's",
        "level": "Pro"
    }]) db.c1.mapReduce(   
    function() {
       var key = {
         day: this.day,
         group: this.group
       };
       var ret = {
         'count': 1,
         'divisions': [{
           'division': this.division,
              'count': 1,
              'levels':[{
                'level': this.level,
                'count': 1
              }]
         }]
       };  emit(key, ret);
    },
       function(key,values) {
         var c = 0;
         var divisions = {};
         var levels = {};
         for(var i=0,ic=values.length;i<ic;++i){
           c += values[i].count;
           division_key = values[i].divisions[0]['division'];
           if(division_key in divisions){
             divisions[ division_key ]['count'] += 1;
             divisions[ division_key ]['levels'].push( values[i].divisions[0]['levels'])
           }else{
             divisions[ division_key ] = {
               count: 1,
               levels: values[i].divisions[0]['levels']
             }
           }
         }
         var divisions_ret = [];
         for(var k in divisions){
           var levels={};
           for(var m=0,mc=divisions[k]['levels'].length;m<mc;++m){
            level_key = divisions[k]['levels'][m]['level'];
            if(level_key in levels){
              levels[ level_key ]['count'] += 1;
            }else{
              levels[ level_key ] = {
                'count': 1,
                'level': level_key
              }
            }
           }
           var level_ret = [];
           for(var n in levels){
             level_ret.push({
               'level': n,
               'count': levels[n]['count']
             });
           }
           divisions_ret.push({
             'division': k,
             'count': divisions[k]['count'],
             'levels': level_ret
           });
         }
         var ret = {
         'count': c,
         'divisions': divisions_ret
       };
       return ret;
       },
       {
          out: "a_result",
          query: {}
       }
    );

    result:


        "_id" : {
            "day" : "Saturday", 
            "group" : "nonpro"
        }, 
        "value" : {
            "count" : 3.0, 
            "divisions" : [
                {
                    "division" : "Women's", 
                    "count" : 1.0, 
                    "levels" : [
                        {
                            "level" : "BB", 
                            "count" : 1.0
                        }
                    ]
                }, 
                {
                    "division" : "Men's", 
                    "count" : 2.0, 
                    "levels" : [
                        {
                            "level" : "BB", 
                            "count" : 1.0
                        }, 
                        {
                            "level" : "undefined", 
                            "count" : 1.0
                        }
                    ]
                }
            ]
        }
    }

        "_id" : {
            "day" : "Saturday", 
            "group" : "pro"
        }, 
        "value" : {
            "count" : 2.0, 
            "divisions" : [
                {
                    "division" : "Women's", 
                    "count" : 1.0, 
                    "levels" : [
                        {
                            "level" : "Pro", 
                            "count" : 1.0
                        }
                    ]
                }, 
                {
                    "division" : "Men's", 
                    "count" : 1.0, 
                    "levels" : [
                        {
                            "level" : "Pro", 
                            "count" : 1.0
                        }
                    ]
                }
            ]
        }
    }

        "_id" : {
            "day" : "Sunday", 
            "group" : "nonpro"
        }, 
        "value" : {
            "count" : 1.0, 
            "divisions" : [
                {
                    "division" : "Coed", 
                    "count" : 1.0, 
                    "levels" : [
                        {
                            "level" : "BB", 
                            "count" : 1.0
                        }
                    ]
                }
            ]
        }
    }

  • Lv 1

    好文章, 值得收藏


登录后回复
 

与 萌阔论坛 的连接断开,我们正在尝试重连,请耐心等待