Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB double $group aggregation

Tags:

mongodb

I have several documents that looks like this:

{
        "_id" : ObjectId("50b59cd75bed76f46522c34e"),
        "player_id" : 0,
        "league_id" : 2,
        "results" : [
                {   "discipline" : "football",
                    "score" : 25.15
                },
                {
                        "discipline" : "basketball",
                        "score" : 21.24
                },
                {
                        "discipline" : "cycling",
                        "score" : 68.19
                },]
}

I try to aggregate this data. First unwind results array, then leave only "football" and "cycling", next count average result. This part I did, and it is working. My code:

db.grades.aggregate(
    {$unwind:"$results"},
    {$match: {$or: [{"results.discipline":"football"},{"results.discipline":"cycling"} ]}},
    {$group:{_id:{player_id:"$player_id",league_id:"$league_id"}, 'average':{$avg:"$results.score"}}},
    )

Then I try to aggregate by league_id, it means, average players results in specific leagues, add to code above: {$group:{_id:"$_id.league_id",aver_league:{$avg:$average}}}

And now code looks like:

db.grades.aggregate(
        {$unwind:"$results"},
        {$match: {$or: [{"results.discipline":"football"},{"results.discipline":"cycling"} ]}},
        {$group:{_id:{player_id:"$player_id",league_id:"$league_id"}, 'average':{$avg:"$results.score"}}},
{$group:{_id:"$_id.league_id",aver_league:{$avg:$average}}}
        )

Console displays: JavaScript execution failed: ReferenceError: $average is not defined. What is wrong? Where did I make a mistake? Is it possible to aggregate by _id.league_id?

like image 418
tostao Avatar asked Oct 03 '22 19:10

tostao


1 Answers

Try this pipeline:

[
 {$unwind:"$results"}, 
 {$match: {"results.discipline":{$in:["football", "basketball"]}}}, 
 {$group{_id:{player_id:"$player_id",league_id:"$league_id"}, 'average':{$avg:"$results.score"}}} 
]

it works for me with your doc:

{
"result" : [
    {
        "_id" : {
            "player_id" : 0,
            "league_id" : 2
        },
        "average" : 23.195
    }
],
"ok" : 1
}

UPD. If you want to group again, by league_id:

[{$unwind:"$results"}, 
{$match: {"results.discipline":{$in:["football", "basketball"]}}}, 
{$group:{_id:{player_id:"$player_id",league_id:"$league_id"}, 'average':{$avg:"$results.score"}  }}, 
{$group:{_id:"$_id.league_id", 'average':{$avg:"$average"}  }} ]

{ "result" : [ { "_id" : 2, "average" : 23.195 } ], "ok" : 1 }
like image 62
Artem Mezhenin Avatar answered Oct 12 '22 10:10

Artem Mezhenin