1

I have a query that returns a single document but have a map field. I would like to sort the map elements, is this possible?

The data is something like this:

Calendars:

{
    "_id" : "1f5c0468-3249-4eee-ae65-79fc134f37c7",
    "countryId" : "60a562ba-43d1-48b3-bd07-7aebbb2c0123",
    "name" : "Bangladesh Holiday 2019",
    "year" : 2019,
    "holidays" : {
        "2019-02-21" : "Language Martyrs' Day",
        "2019-03-17" : "Sheikh Mujibur Rahman's birthday",
        "2019-03-26" : "Independence Day",
        "2019-04-14" : "Bengali New Year",
        "2019-04-21" : "Shab e-Barat",
        "2019-05-01" : "May Day",
        "2019-05-19" : "Buddha Purnima",
        "2019-05-31" : "Jumatul Bidah",
        "2019-06-01" : "Night of Destiny",
        "2019-06-02" : "Night of Destiny",
        "2019-06-03" : "Compensate leave for Night of Destiny",
        "2019-06-04" : "Eid al-Fitr",
        "2019-06-05" : "Eid ul-Fitr",
        "2019-06-06" : "Eid ul-Ftr Holiday",
        "2019-08-09" : "Compensate leave for Eid ul-Adha",
        "2019-08-11" : "Eid ul-Adha Day 1",
        "2019-08-12" : "Eid ul-Adha Day 2",
        "2019-08-13" : "Eid ul-Adha Day 3",
        "2019-08-15" : "National Mourning Day",
        "2019-08-23" : "Janmashtami",
        "2019-09-10" : "Ashura",
        "2019-10-08" : "Durga Puja",
        "2019-11-10" : "Eid e-Milad-un Nabi",
        "2019-12-16" : "Victory Day",
        "2019-12-25" : "Christmas Day"
    }
}

The simple query to get a particular document is like this:

db.getCollection('calendars').find({ "_id" : "1f5c0468-3249-4eee-ae65-79fc134f37c7" })

Now, is it possible to sort the map of holidays by date?

Hardik Shah
  • 4,042
  • 2
  • 20
  • 41
Borgy Manotoy
  • 1,960
  • 5
  • 27
  • 42
  • store result in java script veritable and do sorting . take help from https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key – sandeep rawat Aug 08 '19 at 09:14
  • Where is the array field? And how you want to sort it? – lprakashv Aug 08 '19 at 09:29
  • sorry it should be map, my bad – Borgy Manotoy Aug 08 '19 at 09:40
  • you can use `objectToArray` to then unwind your data, sort it and group it together via the aggregation framework if you are on the right version See for example: https://docs.mongodb.com/manual/reference/operator/aggregation/objectToArray/ – pandaadb Aug 08 '19 at 09:52

1 Answers1

4

Based on your sample JSON: (As far as I understood)

  • Date is key (We must have some mechanism to convert the key to value)
  • Date is a string (We must have to convert String date to Date object)
  • Then sort on date
  • Wrap up whole structure again same as sample JSON but should be sorted

Below is the result of using aggregation:

db.Collection.aggregate([
    { $match: { "_id" : "1f5c0468-3249-4eee-ae65-79fc134f37c7" }}, // Let's fetch particular document
    { $project: {
        countryId: 1,
        name: 1,
        year: 1,
        holidays: { $objectToArray: "$holidays" }, // Let's convert Object to Array first
    }},
    { $unwind: "$holidays" }, // Let's unwind So we can easily convert String date to Date object
    { $addFields: {
      convertedDate: { $toDate: "$holidays.k" } // Let's convert string date to date object
    }},
    { $sort: { "convertedDate": -1 }}, // let's sort converted date (-1 or 1)
    { $group: {  // Let's wrap up whole unwinded object to single
      _id: "$_id",
      countryId: {$first: "$countryId"},
      name: {$first: "$name"},
      year: {$first: "$year"},
      holidays: {$push: "$holidays"} 
    }},
    { $project: { // Let's convert holiday to object again but this time it would be sorted
        countryId: 1,
        name: 1,
        year: 1,
        holidays: { $arrayToObject: "$holidays" }
    }}
])

Output:

{
    "_id" : ObjectId("5d4be8738ac090b7119314a3"),
    "countryId" : "60a562ba-43d1-48b3-bd07-7aebbb2c0123",
    "name" : "Bangladesh Holiday 2019",
    "year" : 2019,
    "holidays" : {
        "2019-12-25" : "Christmas Day",
        "2019-12-16" : "Victory Day",
        "2019-11-10" : "Eid e-Milad-un Nabi",
        "2019-10-08" : "Durga Puja",
        "2019-09-10" : "Ashura",
        "2019-08-23" : "Janmashtami",
        "2019-08-15" : "National Mourning Day",
        "2019-08-13" : "Eid ul-Adha Day 3",
        "2019-08-12" : "Eid ul-Adha Day 2",
        "2019-08-11" : "Eid ul-Adha Day 1",
        "2019-08-09" : "Compensate leave for Eid ul-Adha",
        "2019-06-06" : "Eid ul-Ftr Holiday",
        "2019-06-05" : "Eid ul-Fitr",
        "2019-06-04" : "Eid al-Fitr",
        "2019-06-03" : "Compensate leave for Night of Destiny",
        "2019-06-02" : "Night of Destiny",
        "2019-06-01" : "Night of Destiny",
        "2019-05-31" : "Jumatul Bidah",
        "2019-05-19" : "Buddha Purnima",
        "2019-05-01" : "May Day",
        "2019-04-21" : "Shab e-Barat",
        "2019-04-14" : "Bengali New Year",
        "2019-03-26" : "Independence Day",
        "2019-03-17" : "Sheikh Mujibur Rahman's birthday",
        "2019-02-21" : "Language Martyrs' Day"
    }
}
Hardik Shah
  • 4,042
  • 2
  • 20
  • 41