How to retrieve keys and values from a dynamic map

Hello everyone.

I’m quite new working with Mongo and I have a question that I wasn’t able to solve reading info and finding similar issues.

In my application we had an initial bad design and we used Java maps to model our document. This wouldn’t be a problem if it was not because we put in the key a dynamic value instead of a fixed one and put inside the key and the value.

I will clarify this with an example:

{
  "_id": "myId",
  "plannedMap": {
    "entryKey_1": "2022-10-10T20:32:20Z",
    "entryKey_2": "2022-10-11T20:32:20Z"
  },
"executedMap": {
    "2022-10-11T20:32:20Z": [
      {
        "calendarEntryKey": "entryKey_2",
        "count": 0,
        "quantity": 0,
        "executed": true
      }
}

What I need is to get each combination of entryKeyX - date - executedValue and save it in another collection to remove this one.

The problem I have is how to get the key and value from plannedMap. With this, i could go to executedMap and retrieve the values.

Or maybe it’s easier get them directly from executedMap, but i didn’t find a way to do it without knowing the key of the map.

Thanks in advance.
Regards.

Indeed a bad design. I am pretty sure there is anti-pattern for that. The remedy is the attribute pattern. The flexible schema nature of MongoDB should allow us to migrate toward a better implementation easily.

In the mean time, I think that $objectToArray might provide you a way to find the dynamic keys you are looking for. Using $objectToArray for plannedMap in you sample input document gives:

c.aggregate( { "$set" : { "plannedMap" : { $objectToArray : "$plannedMap"}}})
{ _id: 'myId',
  plannedMap: 
   [ { k: 'entryKey_1', v: '2022-10-10T20:32:20Z' },
     { k: 'entryKey_2', v: '2022-10-11T20:32:20Z' } ],
  executedMap: 
   { '2022-10-11T20:32:20Z': 
      [ { calendarEntryKey: 'entryKey_2',
          count: 0,
          quantity: 0,
          executed: true } ] } }

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