Unable to sort documents after grouping mongodb aggregation framework

so i am trying to sort notifications array of user by it’s insertion date (i want the latest one on top) but it seems to be not working am i missing something ?

here’s the template for data:

{
  _id: "628ceeae3df06d49419f0bb4",
  name: "John",
  notifications: [
    {_id: "someIdA", details: "xyz", dateTime: "1653321337762"},
    {_id: "someIdB", details: "jkl", dateTime: "1653321337762"}
    {_id: "someIdC", details: "abc", dateTime: "1653321321323"}
    {_id: "someIdD", details: "lmn", dateTime: "1653123412341"}
  ]
}

and the aggregation pipeline that i’m trying:


const foundUser = await users.aggregate([
{
$match: {
_id: mongoose.Types.ObjectId(userId)
}
},
{
$project: {
notifications: 1,
_id: 0
}
},
{
$sort: {
_id: -1
}
}
])

If you remove your $sort you will see that documents after the $project look like:

notifications: [
    {_id: "someIdA", details: "xyz", dateTime: "1653321337762"},
    {_id: "someIdB", details: "jkl", dateTime: "1653321337762"}
    {_id: "someIdC", details: "abc", dateTime: "1653321321323"}
    {_id: "someIdD", details: "lmn", dateTime: "1653123412341"}
  ]

That is, all fields projected out except for notifications. So as you can see, your $sort:{_id:-1} does not make sense because you do not have a field named _id anymore.

If you really want to sort on the top level _id:628ceeae3df06d49419f0bb4, you need to remove _id:0 from your $project.

But, if you want to sort based on the _id within the notifications array and keep the result as an array within each top level document, you will need to use $sortArray.

If you do not want a sorted array within a top level document, you will need an $unwind stage before the $sort stage.

The exact scenario depends on your desired result. If you publish expected resulting documents, the help will be more precise.

alright it’s done, so the problem was exactly the not use of $unwind

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.