@@ -96,6 +96,19 @@ However, if the negated portion of the query is inside of an
9696:query:`$elemMatch` expression, then you *can* use the positional
9797operator to update this field.
9898
99+ Multiple Array Matches
100+ ~~~~~~~~~~~~~~~~~~~~~~~
101+
102+ The positional :update:`$` update operator behaves ambiguously when filtering
103+ on multiple array fields.
104+
105+ When the server executes an update method, it first runs a query to determine
106+ which documents you want to update. If the update filters documents on multiple
107+ array fields, the subsequent call to the positional :update:`$` update operator
108+ doesn't always update the required position in the array.
109+
110+ For more information, see the :ref:`example <multiple-array-match>`.
111+
99112Examples
100113--------
101114
@@ -250,6 +263,66 @@ criteria, namely the second embedded document in the array:
250263 ]
251264 }
252265
266+ .. _multiple-array-match:
267+
268+ Update with Multiple Array Matches
269+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
270+
271+ The positional :update:`$` update operator behaves ambiguously when the
272+ query has multiple array fields to filter documents in the collection.
273+
274+ Consider a document in the ``students_deans_list`` collection, which holds
275+ arrays of student information:
276+
277+ .. code-block:: javascript
278+
279+ db.students_deans_list.insertMany( [
280+ {
281+ _id: 8,
282+ activity_ids: [ 1, 2 ],
283+ grades: [ 90, 95 ],
284+ deans_list: [ 2021, 2020 ]
285+ }
286+ ] )
287+
288+ In the following example, the user attempts to modify the ``deans_list`` field,
289+ filtering documents using the ``activity_ids``, ``deans_list``, and ``grades``
290+ fields, and updating the 2021 value in the ``deans_list`` field to 2022:
291+
292+ .. code-block:: javascript
293+
294+ db.students_deans_list.updateOne(
295+ { activity_ids: 1, grades: 95, deans_list: 2021 },
296+ { $set: { "deans_list.$": 2022 } }
297+ )
298+
299+ When the server executes the ``updateOne`` method above, it filters
300+ the available documents using values in the supplied array fields.
301+ Although the ``deans_list`` field is used in the filter, it is not the field
302+ used by the positional :update:`$` update operator to determine which position
303+ in the array to update:
304+
305+ .. code-block:: javascript
306+
307+ db.students_deans_list.find( { _id: 8 } )
308+
309+ Example output:
310+
311+ .. code-block:: javascript
312+
313+ {
314+ _id: 8,
315+ activity_ids: [ 1, 2 ],
316+ grades: [ 90, 95 ],
317+ deans_list: [ 2021, 2022 ]
318+ }
319+
320+ The ``updateOne`` method matched the ``deans_list`` field on 2021, but the
321+ positional :update:`$` update operator instead changed the 2020 value to 2022.
322+
323+ To avoid unexpected results when matching on multiple arrays, instead
324+ use the filtered positional operator :update:`$[<identifier>]`.
325+
253326.. seealso::
254327
255328 - :method:`db.collection.update()`
0 commit comments