How to update the nested array object with update pipeline

Hi,

I am trying to update the nested array based on filter condition, and i am struggling to update nested array. please suggest how it can be written.

Schema:

{
    "_id": "67448af8-a68b-4d08-8948-2cddca57d708",
    "links": [{
        "linkType": "Org",
        "linkPath": "0923689a-e009-4d67-8db5-5ba40f840bf3/facd3c31-dbfd-4097-9a27-0d862bb0c8e9",
        "status": "Activated",
        "createdOn": {
            "$date": "2022-07-26T14:49:38.780Z"
        },
        "createdBy": ""
    }],
    "memberOfGroups": [],
    "roles": [
        "_id":"123",
        "sources":[]
     ]
}```

i am using below pipeline but not able to update the role sources array.

```db.principals.update({ _id: "67448af8-a68b-4d08-8948-2cddca57d708" }, [
    { $set: { "memberOfGroups": { $ifNull: ["$memberOfGroups", []] } } },
    { $set: { "roles": { $ifNull: ["$roles", []] } } },
    {
        $set: {
            "memberOfGroups": {
                $cond: [
                    {
                        $ne: ["$memberOfGroups._id", "ba93384d-d18a-4b36-9a24-7d3ebb1619d7"]
                    },
                    {
                        $concatArrays: [
                            "$memberOfGroups.items",
                            [
                                {
                                    _id: "ba93384d-d18a-4b36-9a24-7d3ebb1619d7",
                                    name: "test group"
                                }
                            ]
                        ]
                    },
                    { $concatArrays: ["$memberOfGroups.items", []] }
                ]
            }
        }
    },

    {
        $set: {
            "roles": {
                $cond: [
                    {
                        $ne: ["$roles._id", "ba93384d-d18a-4b36-9a24-7d3ebb1619d7"]
                    },
                    {
                        $concatArrays: [
                            "$roles.items",
                            [
                                {
                                    _id: "ba93384d-d18a-4b36-9a24-7d3ebb1619d7",
                                    name: "test group",
                                    sources: [
                                        {
                                            type: "group",
                                            linkType: "app",
                                            groupId: "ba93384d-d18a-4b36-9a24-7d3ebb1619d7"
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    {}
                ]
            }
        }
    },
    {
        $set: {
            roles: {
                $reduce: {
                    input: { $ifNull: ["$roles", []] },
                    initialValue: { role: { _id: "0923689a-e009-4d67-8db5-5ba40f840bf3", name: "testRole", sources: [{ type: "group", linkType: "org" }] }, sources: [{ type: "group", linkType: "org", groupid: "0923689a-e009-4d67-8db5-5ba40f840bf3" }] },
                    in: {
                        $cond: [{ $eq: ["$$this.roleid", "0923689a-e009-4d67-8db5-5ba40f840bf3"] },
                        {
                            $cond: [{ $ne: ["$$this.sources.groupId", "0923689a-e009-4d67-8db5-5ba40f840bf3"] },

                            {

                                $concatArrays: ["$$this.sources",
                                    "$$value.sources",
                                ]

                            },

                            {$concatArrays: ["$$this.sources",[]]}

                            ],
                        },
                        {}
                        ]
                    }
                }
            }
        }
    }
], { "multi": true })```

In the above third stage is not working properly where i am trying to insert role array item source array, please help on this.

Thanks,
Shyam Sohane

Hi @Shyam_Sohane,

I ran the provided update operation on a test environment and ended up getting the following output document:

{
    _id: '67448af8-a68b-4d08-8948-2cddca57d708',
    links: [
      {
        linkType: 'Org',
        linkPath: '0923689a-e009-4d67-8db5-5ba40f840bf3/facd3c31-dbfd-4097-9a27-0d862bb0c8e9',
        status: 'Activated',
        createdOn: '2022-07-26T14:49:38.780Z',
        createdBy: ''
      }
    ],
    memberOfGroups: [
      {
        _id: 'ba93384d-d18a-4b36-9a24-7d3ebb1619d7',
        name: 'test group'
      }
    ],
    roles: {}
  }

As I understand it, this is of course not what you are wanting.

In the above third stage is not working properly where i am trying to insert role array item source array, please help on this.

Can you clarify which part specifically of the update is attempting to achieve what you mentioned in the above and what the issue is when you mean “is not working properly”? From the third $set operator, I cannot see any reference to sources or roles fields. However, please correct me if I am wrong here.

In saying so, I understand that you have provided the schema already but could you also provide the following information:

  1. MongoDB Version
  2. Use case details
  3. 3-5 sample documents
  4. Expected / desired output

If it suits your use case, perhaps maybe use of the $[<identifier>] may help.

Regards,
Jason