What behavior would this Mongo query have - double nested documents

I’m having a discussion with one of my developers.

Here’s a useful snippet of relations:
Collection: ‘Property’
Property hasMany Spaces
Property hasMany Items
Spaces hasMany Items

Note that an Item subdocument may exist in a Property, and it may exist within a Space in a Property.

When this query is made, it is known that the item exists in a space, and the logic to determine that also easily provides the unique identifier for the Space.

My developer has written:

updateOne(
  {
    _id: propertyId,
   'spaces.items.id': itemId
  }, 
  {
    $set: {
      'spaces.$[].items.$[item].<property>: value'
    }
  }
)

Can I know for certain that this query will look for one item, and after it finds it, stop looking? It seems to me that the query should go:

Find the property
Look in each space for an item with the given id

But I guess my developer thinks it would go:

Find the property
i = 0
Look in space[i].
Look in items
If item with itemId, update then return
Else i++

Thanks for any help.

Edit to add:
I notice that $ is actually called the “all positional operator” and:

indicates that the update operator should modify all elements in the specified array field.
https://www.mongodb.com/docs/manual/reference/operator/update/positional-all/#:~:text=Definition,-%24[]&text=The%20all%20positional%20operator%20%24[],in%20the%20specified%20array%20field.&text=For%20an%20example%2C%20see%20Update%20All%20Elements%20in%20an%20Array.

So in a battle of wills with my junior developer, would it be fair to say that AT BEST, his use of $ is a misuse since the intended usage of $ is to modify all elements in the specified array field?

Why battle?

The documentation is clear about $[]

The all positional operator $[] indicates that the update operator should modify all elements in the specified array field.

Ditto for $[item]

Use in conjunction with the arrayFilters option to update all elements that match the arrayFilters conditions in the document or documents that match the query conditions.

All examples in both documentation pages clearly show that all matching elements are updated.

But why battle?

Simply test the code. If you do you might get an error because your are using $[item] and I don’t see a corresponding arrayFilters option.

2 Likes

Following up on my previous answer.

Thanks to @Aasawari’s reply in another thread, I realized that the confusion might come from the fact there is another array update positional operator to only update the first element that match the query.

$ - to update the first matching element
$[] - to update all the matching element
$[name] - to update all the matching element based on arrayFilters.

4 Likes