How to update multiple embedded documents in an array

Use case:
A Widget has many Gizmos. I’m using the Embedded Document pattern.

I need to update (potentially) each Gizmo. Can I do this with one updateOne? I do understand that I need updateOne instead of updateMany since I’m working within ONE document in a collection.

I’m thinking that this won’t be possible because the query selector would need to specify which embedded documents to update.

Essentially what I’m looking for is something like:

`Widget.updateOne({
  where: {_id: widget.id},
  update: {
    {gizmo.color: red WHERE gizmoId: gizmo[0].id},
    {gizmo.color: blue WHERE gizmoId: gizmo[1].id}
  }
})`

This has been in my bookmarks for a long time.

The following seems to work.

Starting with the collection:

{ _id: ObjectId("639dd1cf0305687fe1a600b8"),
  gizmos: [ { id: 1, color: 2 }, { id: 3, color: 4 } ] }

You may update using multiple arrayFilters such as:

filter1 = { "filter1.id" : 1 }
filter3 = { "filter3.id" : 3 }
update1 = { 'gizmos.$[filter1].color': red }
update3 = { 'gizmos.$[filter3].color': blue }
c.updateOne( {} ,
    { "$set" : { ...update1 , ...update2 } } ,
    { arrayFilters : [ filter1 , filter3 ] } )
1 Like