20

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
}

1 Answer 1

41

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
    } }
])
Sign up to request clarification or add additional context in comments.

1 Comment

They really should put some complex examples like this one in their docs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.