Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort sub-arrays in an Aggregate Result

Tags:

I have three documents:

{
    "id_user": "t57092501745ad6285ac58c22",
    "name": "Day #1",
    "date": {
        "$date": "2016-04-21T20:50:00.190Z"
    },
    "text": "My text"
}

{
    "id_user": "t57092501745ad6285ac58c22",
    "name": "Day #2",
    "date": {
        "$date": "2016-04-22T20:50:00.190Z"
    },
    "text": "My text"
}

{
    "id_user": "t57092501745ad6285ac58c22",
    "name": "Day #3",
    "date": {
        "$date": "2016-04-22T20:51:00.190Z"
    },
    "text": "My text"
}

and I need to group these for day, so I do:

{
    "$match": {
        "id_user": "t57092501745ad6285ac58c22"
    }
}, {
    "$sort": {
        "date": -1
    }
}, {
    "$group": {
        "_id": {
            $dayOfYear: "$date"
        },
        "data": {
            "$push": {
                "id_user": "$id_user",
                "name": "$name",
                "date": "$date",
                "text": "$text"
            },
        },
    }

}

and the result is:

{
    {
        _id: 113,
        data: [{
            "id_user": "t57092501745ad6285ac58c22",
            name: "Day #1",
            date: "2016-04-22T20:51:00.190Z",
            text: "My text"
        }]
    }, {
        _id: 114,
        data: [{
            "id_user": "t57092501745ad6285ac58c22",
            name: "Day #3",
            date: "2016-04-23T20:51:00.190Z",
            text: "My text"
        }, {
            "id_user": "t57092501745ad6285ac58c22",
            name: "Day #2",
            date: "2016-04-23T20:50:00.190Z",
            text: "My text"
        }]
    }
}

and it's ok, but the order is not what I need:

{ Day #1 }, { Day #3, Day #2 }

if I change the sort to { "date": 1 } I can invert the order of the 2 groups, this way:

{ Day #3, Day #2 }, { Day #1 }

but I don't know how tho change also the order inside the sub-array, to obtain the correct:

{ Day #1 }, { Day #2, Day #3 }

What's the correct way?

like image 210
shaithana Avatar asked Apr 23 '16 23:04

shaithana


1 Answers

If you want the items in the "array" to be in "ascending" order, then your $sort order is wrong, and you need to reverse it. Also output from $group as a "document" is not ordered in any way. So if you want a specific order then you need to actually $sort on the returned _id as well:

[
    { "$match": {
        "id_user": "t57092501745ad6285ac58c22"
    }},
    { "$sort": { "date": 1 } }
    { "$group": {
        "_id": { "$dayOfYear": "$date" },
        "data": {
            "$push": {
                "id_user": "$id_user",
                "name": "$name",
                "date": "$date",
                "text": "$text"
            }
        }
    }},
    { "$sort": { "_id": 1 } }
]

Then both orders are then correct

like image 140
Blakes Seven Avatar answered Sep 28 '22 01:09

Blakes Seven