Belegnar
Belegnar

Reputation: 877

Update mongo array elements field from its other field

Let's assume following document

{
    "companies": [
        {"id": 1, "name": "Company 1", "new_name": "New company 1"},
        {"id": 2, "name": "Company 2", "new_name": "New company 2"}
    ]
}

Is there a way I can reference element of array by itself to migrate to scheme

{
    "companies": [
        {"id": 1, "name": "New company 1", "new_name": "New company 1"},
        {"id": 2, "name": "New company 2", "new_name": "New company 2"}
    ]
}

within a single call to update without scripting with forEach in mongo 4.2? Something like

update(
...
{
  "companies.$[].name": "$companies.<???>.new_name"
}
)

Upvotes: 1

Views: 43

Answers (1)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17915

To access another field's value in a query you need to use aggregation, taking advantage of executing aggregation pipeline in .update()'s which got introduced in MongoDB version 4.2, try below query :

update(
    ...
    [
        {
          $addFields: { // will replace existing field with new value
            companies: {
              $map: { // Iterates on an array & creates a new one
                input: "$companies",
                in: { $mergeObjects: [ "$$this", { name: "$$this.new_name" } ] } // `mergeObjects` will merge two objects `name` field will be replace in current object i.e; `$$this`
              }
            }
          }
        }
      ]
    )

Test : You can test aggregation pipeline here : mongoplayground

Note : Seems to be using aggregation is only option to do this in one call, but downside could be only if your array is too huge, cause $map has to re-write entire array again.

Upvotes: 1

Related Questions