How to change a type of a array using runCommand

Hello.

I would like to modify my array’s type from ObjectId to Object, copying the values ​​of each element of the array into a new object. I need to do this using liqbase and I believe the best way would be using runCommand. The big problem is that I can’t use the element’s expression as a value in the new object, like this:

<ext:command>
                {
                    update: "driver_delivery_route",
                    updates: [
                         {
                            q: {_id: ObjectId('61f82b33c0b9053da2197759')},
                            u: {
                                $set: { "orders.$[element]": {
                                    _id: "orders.$[element].somethingMaybe" // this is always interpreted like string
                                } }
                            },
                            arrayFilters: [ { "element": { $ne: null } } ]
                         }
                    ]
                }
            </ext:command>

current:

{
  "orders": [ObjectId('....'), ObjectId('....')]
}

expected:

{
  "orders": [{_id: ObjectId('....')}, {_id: ObjectId('....')}]
}

Does anyone know how to do this or have another suggestion to solve this problem?
Thank you!

Hi @Matheus_Souza and welcome in the MongoDB Community :muscle: !

I would do an aggregation pipeline like this. Maybe there is a more simple solution but… I like it :wink: !

[
  {
    '$project': {
      'orders': {
        '$map': {
          'input': '$orders', 
          'in': {
            '_id': '$$this'
          }
        }
      }
    }
  }, {
    '$merge': {
      'into': 'coll', 
      'on': '_id', 
      'whenMatched': 'merge', 
      'whenNotMatched': 'fail'
    }
  }
]

I tested on a couple of docs and I have the correct result in the end. I’m basically overwriting the orders field.

Cheers,
Maxime.

Hi @ MaBeuLux88!
Thanks for the answer. This solved my problem!
Here’s the complete code:

<ext:runCommand>
            <ext:command>
                {
                   aggregate: "driver_delivery_route",
                   pipeline: [
                      {
                        '$project': {
                          'orders': {
                            '$map': {
                              'input': '$orders',
                              'in': {
                                '_id': '$$this'
                              }
                            }
                          }
                        }
                      }, {
                        '$merge': {
                          'into': 'driver_delivery_route',
                          'on': '_id',
                          'whenMatched': 'merge',
                          'whenNotMatched': 'fail'
                        }
                      }
                    ],
                   cursor: { }
                }
            </ext:command>
</ext:runCommand>
1 Like

I’m glad I was able to help!
Cheers!

1 Like

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