$push into array while $set'ing fields of existing elements

Hi @Jon_Madden,

Ok I se the issue, with this document structure and array nesting you cannot update and push to the same array in a single operation. BTW, there is no need to do an elemMatch if you want to find just one field and you can reference it using “.”.

You will have to seperate those into 2:

  1. Update the description
db.updateTest.updateOne({"userJourneyEvents.id" : 'eid'},[{$set : { 'userJourneyEvents.$[event].touchpoints.$[touchpoints].description' : 'description' }
 }],{ arrayFilters: [ { "event.id": "eid" } , { "touchpoints": "tpid0" } ]});
  1. Push new element.
db.updateTest.updateOne({"userJourneyEvents.id" : 'eid'},{
 $push : {'userJourneyEvents.$[event].touchpoints':{
      '$each': [
        {
          id: 'new_id',
          kind: 'tools',
          description: ''
        }
      ],
      '$sort': { kind: 1 }
    }}},{ arrayFilters: [ { "event.id": "eid" } ]});

If you need ACID consistency on those you should use transactions to perform them in a single transaction.

Another option is to build the array for this document on the client side and update the entire array all together:

db.updateTest.updateOne({"userJourneyEvents.id" : 'eid'},{$set : { 'userJourneyEvents.$[event].touchpoints' :
[
        {
          "id": "tpid0",
          "kind": "tools",
          "description": "description"
        },
        {
          "id": "new_id",
          "kind": "tools"
        }
      ]
}},{ arrayFilters: [ { "event.id": "eid" } ]});

I thought on trying aggregation pipeline updates with $zip and $map but it super complex and not worth the effort.

Please let me know if you have any additional questions.

Best regards,
Pavel