Home > database >  Sorting an array of objects in MongoDB collection
Sorting an array of objects in MongoDB collection

Time:09-18

I have a collection in a MongoDB with a document like below:

{
  "_id": "63269e0f85bfd011e989d0f7",
  "name": "Aravind Krishna",
  "mobile": 7309454620,
  "email": "[email protected]",
  "password": "$2b$12$0dOE/0wj6uX604h3DZpGxuO/L.fZg7KCm7mOGsNMkarSaeG2C/Wvq",
  "orders": [
    {
      "paymentIntentId": "pi_3LjFDtSHVloG65Ul0exLkzsO",
      "cart": [array],
      "amount": 3007,
      "created": 1663475717,
      "_id": "6326a01344f26617fc1a65d6"
    },
    {
      "paymentIntentId": "pi_3LjFFUSHVloG65Ul1FQHlZ9H",
      "cart": [array],
      "amount": 389,
      "created": 1663475816,
      "_id": "6326a07744f26617fc1a65d8"
    }
  ],
  "__v": 0
}

I wanted to get only the orders array sorted by the created property in both ascending and descending manner. As we can see here that orders field inside this document is an array of objects. Please give a solution if you have one. I tried the sortArray method but it is giving an error. Please help.

For some assistance the output should look something like this:

    {
  "_id": "63269e0f85bfd011e989d0f7",
  "orders": [
    {
      "paymentIntentId": "pi_3LjFDtSHVloG65Ul0exLkzsO",
      "cart": [array],
      "amount": 3007,
      "created": 1663475717,
      "_id": "6326a01344f26617fc1a65d6"
    },
    {
      "paymentIntentId": "pi_3LjFFUSHVloG65Ul1FQHlZ9H",
      "cart": [array],
      "amount": 389,
      "created": 1663475816,
      "_id": "6326a07744f26617fc1a65d8"
    }
  ]
}

See, I got only the orders field but I want it sorted by the created property value both ascending and descending.

CodePudding user response:

As you mentioned the best way to achieve this is to use $sortArray, I'm assuming the error you're getting is a version mismatch as this operator was only recently added at version 5.2.

The other way to achieve the same result as not as pleasant, you need to $unwind the array, $sort the results and then $group to restore structure, then it's easy to add the "other" order by using $reverseArray although I recommend instead of duplicating your data you just handle the "reverse" requirement in code, overall the pipeline will look like so:

db.collection.aggregate([
  {
    $unwind: "$orders"
  },
  {
    $sort: {
      "orders.created": 1
    }
  },
  {
    $group: {
      _id: "$_id",
      asc_orders: {
        $push: "$orders"
      }
    }
  },
  {
    $addFields: {
      desc_orders: {
        "$reverseArray": "$asc_orders"
      }
    }
  }
])

Mongo Playground

  • Related