-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathembedded-arrays.txt
317 lines (245 loc) · 9.25 KB
/
embedded-arrays.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
.. _node-fundamentals-update-array:
===========================
Update Arrays in a Document
===========================
.. meta::
:description: Learn how to use array update operators to modify embedded arrays in documents, including positional, all positional, and filtered positional operators.
.. default-domain:: mongodb
.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol
Overview
--------
In this guide, you can learn how to use the following array update
operators to modify an array embedded within a document:
- :ref:`Positional Operator <first-match-operator>`: ``$``
- :ref:`All Positional Operator <all-match-operator>`: ``$[]``
- :ref:`Filtered Positional Operator <filtered-positional-operator>`: ``$[<identifier>]``
For a list of array update operators, see :manual:`Update Operators
</reference/operator/update-array/>` in the Server
Manual documentation.
Specifying Array Elements
-------------------------
Positional operators specify which array elements to update. You can use these operators to apply updates to the first element, all elements, or
certain elements of an array that match a criteria.
To specify elements in an array with positional operators, use **dot
notation**. Dot notation is a property access syntax for navigating BSON
objects. To learn more, see :manual:`dot notation
</core/document/#std-label-document-dot-notation>`.
.. _first-match-operator:
The First Matching Array Element
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To update the first array element of each document that matches your
query, use the positional operator ``$``.
The positional operator ``$`` references the array matched by the query.
You cannot use this operator to reference a nested array. If you want to
access a nested array, use the :ref:`filtered positional operator <filtered-positional-operator>`.
.. important::
Do not use the ``$`` operator in an ``upsert`` call because the
driver treats ``$`` as a field name in the insert document.
Example
```````
This example uses the following sample document to show how to update
the first matching array element:
.. code-block:: javascript
:copyable: false
{
_id: ...,
entries: [
{ x: false, y: 1 },
{ x: "hello", y: 100 },
{ x: "goodbye", y: 1000 }
]
}
The following code shows how to increment a value in the first array
element that matches a query.
The query matches elements in the ``entries`` array where the value of
``x`` is a ``string`` type. The update increases the ``y`` value by
``33`` in the first matching element.
.. literalinclude:: /code-snippets/crud/arrayFilters.js
:language: javascript
:start-after: start firstArrayElement example
:end-before: end firstArrayElement example
:dedent:
After you run the update operation, the document resembles the
following:
.. code-block:: javascript
:copyable: false
:emphasize-lines: 5
{
_id: ...,
entries: [
{ x: false, y: 1 },
{ x: "hello", y: 133 },
{ x: "goodbye", y: 1000 }
]
}
The example includes the ``entries.x`` field in the
query to match the array that the ``$`` operator applies an update to. If you
omit the ``entries.x`` field from the query while using the
``$`` operator in an update, the driver is unable to identify the
matching array and raises the following error:
.. code-block:: none
:copyable: false
MongoServerError: The positional operator did not find the match needed from the query.
.. _all-match-operator:
Matching All Array Elements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
To perform the update on all array elements of each document that
matches your query, use the all positional operator ``$[]``.
Example
```````
This example uses the following sample documents, which describe phone
call logs, to show how to update all matching array elements:
.. code-block:: javascript
:copyable: false
{
_id: ...,
date: "5/15/2023",
calls: [
{ time: "10:08 AM", caller: "Mom", duration: 67 },
{ time: "04:11 PM", caller: "Dad", duration: 121 },
{ time: "06:36 PM", caller: "Grandpa", duration: 13 }
]
},
{
_id: ...,
date: "5/16/2023",
calls: [
{ time: "11:47 AM", caller: "Mom", duration: 4 },
]
}
The following code shows how to remove the ``duration`` field from
all ``calls`` array entries in the document whose ``date`` is
``"5/15/2023"``:
.. literalinclude:: /code-snippets/crud/arrayFilters.js
:language: javascript
:start-after: start allArrayElement example
:end-before: end allArrayElement example
:dedent:
After you run the update operation, the documents resemble the following:
.. code-block:: javascript
:copyable: false
:emphasize-lines: 5-7
{
_id: ...,
date: "5/15/2023",
calls: [
{ time: "10:08 AM", caller: "Mom" },
{ time: "04:11 PM", caller: "Dad" },
{ time: "06:36 PM", caller: "Grandpa" }
]
},
{
_id: ...,
date: "5/16/2023",
calls: [
{ time: "11:47 AM", caller: "Mom", duration: 4 },
]
}
.. _filtered-positional-operator:
Matching Multiple Array Elements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To perform an update on all embedded array elements of each document
that matches your query, use the filtered positional operator
``$[<identifier>]``.
The filtered positional operator ``$[<identifier>]`` specifies the
matching array elements in the update document. To identify which array
elements to match, pair this operator with ``<identifier>`` in an
``arrayFilters`` object.
The ``<identifier>`` placeholder represents an element of the array
field. You must select a value for ``<identifier>`` that starts with a
lowercase letter and contains only alphanumeric characters.
Usage
`````
You can use a filtered positional operator in an update operation.
An update operation takes a query, an update document, and
optionally, an options object as its parameters.
The following steps describe how to use a filtered positional operator
in an update operation:
1. Format your update document as follows:
.. code-block:: javascript
{ $<operator>: { "<array>.$[<identifier>].<arrayField>": <updateParameter> } }
This update document contains the following placeholders:
- ``$<operator>``: The array update operator
- ``<array>``: The array in the document to update
- ``<identifier>``: The identifier for the filtered positional operator
- ``<arrayField>``: The field in the ``<array>`` array element to update
- ``<updateParameter>``: The value that describes the update
#. Add the matching criteria in the ``arrayFilters`` object. This object
is an array of queries that specify which array elements to include
in the update. Set this object in an ``options`` parameter:
.. code-block:: javascript
arrayFilters: [
{ "<identifier>.<arrayField1>": <updateParameter1> },
{ "<identifier>.<arrayField2>": <updateParameter2> },
...
]
#. Pass the query, the update document, and options to an
update method. The following sample code shows how to call the
``updateOne()`` method with these parameters:
.. code-block:: javascript
await myColl.updateOne(query, updateDocument, options);
Example
```````
This example uses the following sample documents, which describe
shopping lists for specific recipes, to show how to update certain matching array elements:
.. code-block:: javascript
:copyable: false
{
_id: ...,
date: "11/12/2023",
items: [
{ item: "Scallions", quantity: 3, recipe: "Fried rice" },
{ item: "Mangos", quantity: 4, recipe: "Salsa" },
{ item: "Pork shoulder", quantity: 1, recipe: "Fried rice" },
{ item: "Sesame oil", quantity: 1, recipe: "Fried rice" }
]
},
{
_id: ...,
date: "11/20/2023",
items: [
{ item: "Coffee beans", quantity: 1, recipe: "Coffee" }
]
}
Suppose you want to increase the quantity of items you purchase for a
recipe on your ``"11/12/2023"`` grocery trip. You want to double the quantity if
the item meets all the following criteria:
- The item is for the ``"Fried rice"`` recipe.
- The item name does not include the word ``"oil"``.
To double the ``quantity`` value in the matching array
entries, use the filtered positional operator as shown in the following
code:
.. literalinclude:: /code-snippets/crud/arrayFilters.js
:language: javascript
:start-after: start arrayFiltersIdentifier example
:end-before: end arrayFiltersIdentifier example
:emphasize-lines: 6, 11-16
:dedent:
The update multiplied the ``quantity`` value by ``2`` for
items that matched the criteria. The item ``"Sesame oil"`` did not match
the criteria in the ``arrayFilters`` object and therefore was excluded
from the update. The following documents reflect these changes:
.. code-block:: javascript
:copyable: false
:emphasize-lines: 5, 7
{
_id: ...,
date: "11/12/2023",
items: [
{ item: "Scallions", quantity: 6, recipe: "Fried rice" },
{ item: "Mangos", quantity: 4, recipe: "Salsa" },
{ item: "Pork shoulder", quantity: 2, recipe: "Fried rice" },
{ item: "Sesame oil", quantity: 1, recipe: "Fried rice" }
]
},
{
_id: ...,
date: "11/20/2023",
items: [
{ item: "Coffee beans", quantity: 1, recipe: "Coffee" }
]
}