-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
unwind.txt
233 lines (153 loc) · 6.55 KB
/
unwind.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
=====================
$unwind (aggregation)
=====================
.. default-domain:: mongodb
.. contents:: On this page
:local:
:backlinks: none
:depth: 1
:class: singlecol
Definition
----------
.. pipeline:: $unwind
Deconstructs an array field from the input documents to output a
document for *each* element. Each output document is the input
document with the value of the array field replaced by the element.
The :pipeline:`$unwind` stage has one of two syntaxes:
- The operand is a field path:
.. code-block:: javascript
{ $unwind: <field path> }
To specify a field path, prefix the field name with a dollar sign
``$`` and enclose in quotes.
- The operand is a document:
.. versionadded:: 3.2
.. code-block:: javascript
{
$unwind:
{
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
.. list-table::
:header-rows: 1
:widths: 20 20 80
* - Field
- Type
- Description
* - ``path``
- string
- Field path to an array field. To specify a field path, prefix the
field name with a dollar sign ``$`` and enclose in quotes.
* - ``includeArrayIndex``
- string
- Optional. The name of a new field to hold the array index of the
element. The name cannot start with a dollar sign ``$``.
* - ``preserveNullAndEmptyArrays``
- boolean
- Optional. If ``true``, if the ``path`` is null, missing, or an empty array,
:pipeline:`$unwind` outputs the document. If ``false``,
:pipeline:`$unwind` does not output a document if the ``path`` is
null, missing, or an empty array.
The default value is ``false``.
Behaviors
---------
Non-Array Field Path
~~~~~~~~~~~~~~~~~~~~
.. versionchanged:: 3.2
:pipeline:`$unwind` stage no longer errors on non-array operands. If
the operand does not resolve to an array but is not missing, null,
or an empty array, :pipeline:`$unwind` treats the operand as a
single element array.
Previously, if a value in the field specified by the field path is
*not* an array, :method:`db.collection.aggregate()` generates an
error.
Missing Field
~~~~~~~~~~~~~
If you specify a path for a field that does not exist in an input
document or the field is an empty array, :pipeline:`$unwind`, by
default, ignores the input document and will not output documents for
that input document.
.. versionadded:: 3.2
To output documents where the array field is missing, null or an
empty array, use the option ``preserveNullAndEmptyArrays``.
Examples
--------
Unwind Array
~~~~~~~~~~~~
Consider an ``inventory`` with the following document:
.. code-block:: javascript
{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }
The following aggregation uses the :pipeline:`$unwind` stage to output
a document for each element in the ``sizes`` array:
.. code-block:: javascript
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
The operation returns the following results:
.. code-block:: javascript
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
Each document is identical to the input document except for the value
of the ``sizes`` field which now holds a value from the original
``sizes`` array.
.. seealso::
:doc:`/tutorial/aggregation-zip-code-data-set`,
:doc:`/tutorial/aggregation-with-user-preference-data`
``includeArrayIndex`` and ``preserveNullAndEmptyArrays``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 3.2
A collection ``inventory`` has the following documents:
.. code-block:: javascript
{ "_id" : 1, "item" : "ABC", "sizes": [ "S", "M", "L"] }
{ "_id" : 2, "item" : "EFG", "sizes" : [ ] }
{ "_id" : 3, "item" : "IJK", "sizes": "M" }
{ "_id" : 4, "item" : "LMN" }
{ "_id" : 5, "item" : "XYZ", "sizes" : null }
The following :pipeline:`$unwind` operations are equivalent and return
a document for each element in the ``sizes`` field. If the ``sizes``
field does not resolve to an array but is not missing, null, or an
empty array, :pipeline:`$unwind` treats the non-array operand as a
single element array.
.. code-block:: javascript
db.inventory.aggregate( [ { $unwind: "$sizes" } ] )
db.inventory.aggregate( [ { $unwind: { path: "$sizes" } } ] )
The operation returns the following documents:
.. code-block:: javascript
{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
The following :pipeline:`$unwind` operation uses the
``includeArrayIndex`` option to output also the array index of the
array element.
.. code-block:: javascript
db.inventory.aggregate( [ { $unwind: { path: "$sizes", includeArrayIndex: "arrayIndex" } } ] )
The operation unwinds the ``sizes`` array and includes the array index
of the array index in the new ``arrayIndex`` field. If the ``sizes``
field does not resolve to an array but is not missing, null, or an
empty array, the ``arrayIndex`` field is ``null``.
.. code-block:: javascript
{ "_id" : 1, "item" : "ABC", "sizes" : "S", "arrayIndex" : NumberLong(0) }
{ "_id" : 1, "item" : "ABC", "sizes" : "M", "arrayIndex" : NumberLong(1) }
{ "_id" : 1, "item" : "ABC", "sizes" : "L", "arrayIndex" : NumberLong(2) }
{ "_id" : 3, "item" : "IJK", "sizes" : "M", "arrayIndex" : null }
The following :pipeline:`$unwind` operation uses the
``preserveNullAndEmptyArrays`` option to include in the output those
documents where ``sizes`` field is missing, null or an empty array.
.. code-block:: javascript
db.inventory.aggregate( [
{ $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] )
In addition to unwinding the documents where the ``sizes`` is an array
of elements or a non-null, non-array field, the operation outputs,
without modification, those documents where the ``sizes`` field is
missing, null or an empty array:
.. code-block:: javascript
{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 2, "item" : "EFG" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
{ "_id" : 4, "item" : "LMN" }
{ "_id" : 5, "item" : "XYZ", "sizes" : null }