JamesE
JamesE

Reputation: 3923

MongoDB aggregation sort not working

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

Answers (1)

JohnnyHK
JohnnyHK

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

Related Questions