Reputation: 3923
I'm having a problem applying a sort to an aggregation grouping. My raw data looks like the following:
{
"_id" : ObjectId("52deab2fe4b0a491abb54108"),
"type" : "build",
"time" : ISODate("2014-01-21T17:15:27.471Z"),
"data" : {
"buildNumber" : 43,
"buildDuration" : 997308,
"buildProjectName" : "TestABC",
"buildResult" : "SUCCESS"
}
}
I would like to sort this first by buildProjectName and then date. Here is my query:
db.builds.aggregate([
{ $group: {
_id: {
month: { $month: "$time" },
day: { $dayOfYear: "$time" },
year: { $year: "$time" },
buildProjectName: "$data.buildProjectName",
},
buildDuration: { $avg: "$data.buildDuration" }
} },
{ $sort: {buildProjectName: 1, year: 1, month: 1, day: 1} }
])
I've tried switching the order of the sort (i.e.: buildProjectName, day, month, year), but I always get the same result with the dates out of order:
{
"result" : [
{
"_id" : {
"month" : 1,
"day" : 20,
"year" : 2014,
"buildProjectName" : "TestABC"
},
"buildDuration" : 1170723.5
},
{
"_id" : {
"month" : 1,
"day" : 21,
"year" : 2014,
"buildProjectName" : "TestABC"
},
"buildDuration" : 2284863.3333333335
},
{
"_id" : {
"month" : 1,
"day" : 17,
"year" : 2014,
"buildProjectName" : "TestABC"
},
"buildDuration" : 2234662
}
],
"ok" : 1
}
Upvotes: 19
Views: 19594
Reputation: 311835
The fields you're sorting on are part of the _id
so you need to include that in your $sort
field names:
db.builds.aggregate([
{ $group: {
_id: {
month: { $month: "$time" },
day: { $dayOfYear: "$time" },
year: { $year: "$time" },
buildProjectName: "$data.buildProjectName",
},
buildDuration: { $avg: "$data.buildDuration" }
} },
{ $sort: {
'_id.buildProjectName': 1,
'_id.year': 1,
'_id.month': 1,
'_id.day': 1
} }
])
Upvotes: 40