Skip to content

Commit 4d83043

Browse files
committed
DOCS-949 aggregation operator concat
1 parent 82a73b1 commit 4d83043

File tree

3 files changed

+208
-0
lines changed

3 files changed

+208
-0
lines changed

source/reference/aggregation.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ String Operators
210210

211211
These operators manipulate strings within projection expressions.
212212

213+
.. include:: aggregation/concat.txt
214+
:start-after: default-domain:: agg
215+
:end-before: .. begin-examples
216+
213217
.. include:: aggregation/strcasecmp.txt
214218
:start-after: default-domain:: agg
215219

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
=====================
2+
$concat (aggregation)
3+
=====================
4+
5+
.. default-domain:: agg
6+
7+
.. expression:: $concat
8+
9+
.. versionadded:: 2.4
10+
11+
Takes an array of strings, concatenates the strings, and returns the
12+
concatenated string. :expression:`$concat` can only accept an array
13+
of strings.
14+
15+
Use :expression:`$concat` with the following syntax:
16+
17+
.. code-block:: javascript
18+
19+
{ $concat: [ <string>, <string>, ... ] }
20+
21+
If array element has a value of ``null`` or refers to a field that
22+
is missing, :expression:`$concat` will return ``null``.
23+
24+
.. begin-examples
25+
26+
.. example:: Project new concatenated values.
27+
28+
A collection ``menu`` contains the documents that stores
29+
information on menu items separately in the ``section``, the
30+
``category`` and the ``type`` fields, as in the following:
31+
32+
.. code-block:: javascript
33+
34+
{ _id: 1, item: { sec: "dessert", category: "pie", type: "apple" } }
35+
{ _id: 2, item: { sec: "dessert", category: "pie", type: "cherry" } }
36+
{ _id: 3, item: { sec: "main", category: "pie", type: "shepherd's" } }
37+
{ _id: 4, item: { sec: "main", category: "pie", type: "chicken pot" } }
38+
39+
The following operation uses :expression:`$concat` to concatenate
40+
the ``type`` field from the sub-document ``item``, a space `` ``,
41+
and the ``category`` field from the sub-document ``item`` to
42+
project a new ``food`` field:
43+
44+
.. code-block:: javascript
45+
46+
db.menu.aggregate( { $project: { food:
47+
{ $concat: [ "$item.type",
48+
" ",
49+
"$item.category"
50+
]
51+
}
52+
}
53+
}
54+
)
55+
56+
The operation returns the following result set where the ``food``
57+
field contains the concatenated strings:
58+
59+
.. code-block:: javascript
60+
61+
{
62+
"result" : [
63+
{ "_id" : 1, "food" : "apple pie" },
64+
{ "_id" : 2, "food" : "cherry pie" },
65+
{ "_id" : 3, "food" : "shepherd's pie" },
66+
{ "_id" : 4, "food" : "chicken pot pie" }
67+
],
68+
"ok" : 1
69+
}
70+
71+
.. example:: Group by a concatenated string.
72+
73+
A collection ``menu`` contains the documents that stores
74+
information on menu items separately in the ``section``, the
75+
``category`` and the ``type`` fields, as in the following:
76+
77+
.. code-block:: javascript
78+
79+
{ _id: 1, item: { sec: "dessert", category: "pie", type: "apple" } }
80+
{ _id: 2, item: { sec: "dessert", category: "pie", type: "cherry" } }
81+
{ _id: 3, item: { sec: "main", category: "pie", type: "shepherd's" } }
82+
{ _id: 4, item: { sec: "main", category: "pie", type: "chicken pot" } }
83+
84+
The following aggregation uses :expression:`$concat` to
85+
concatenate the ``sec`` field from the sub-document ``item``, the
86+
string ``": "``, and the ``category`` field from the sub-document
87+
``item`` to group by the new concatenated string and perform a
88+
count:
89+
90+
.. code-block:: javascript
91+
92+
db.menu.aggregate( { $group: { _id:
93+
{ $concat: [ "$item.sec",
94+
": ",
95+
"$item.category"
96+
]
97+
},
98+
count: { $sum: 1 }
99+
}
100+
}
101+
)
102+
103+
The aggregation returns the following document:
104+
105+
.. code-block:: javascript
106+
107+
{
108+
"result" : [
109+
{ "_id" : "main: pie", "count" : 2 },
110+
{ "_id" : "dessert: pie", "count" : 2 }
111+
],
112+
"ok" : 1
113+
}
114+
115+
.. example:: Concatenate ``null`` or missing values.
116+
117+
A collection ``menu`` contains the documents that stores
118+
information on menu items separately in the ``section``, the
119+
``category`` and the ``type`` fields. Not all documents have the
120+
all three fields. For example, the document with ``_id`` equal to
121+
``5`` is missing the ``category`` field:
122+
123+
.. code-block:: javascript
124+
125+
{ _id: 1, item: { sec: "dessert", category: "pie", type: "apple" } }
126+
{ _id: 2, item: { sec: "dessert", category: "pie", type: "cherry" } }
127+
{ _id: 3, item: { sec: "main", category: "pie", type: "shepherd's" } }
128+
{ _id: 4, item: { sec: "main", category: "pie", type: "chicken pot" } }
129+
{ _id: 5, item: { sec: "beverage", type: "coffee" } }
130+
131+
The following aggregation uses the :expression:`$concat` to
132+
concatenate the ``type`` field from the sub-document ``item``, a
133+
space, and the ``category`` field from the sub-document ``item``:
134+
135+
.. code-block:: javascript
136+
137+
db.menu.aggregate( { $project: { food:
138+
{ $concat: [ "$item.type",
139+
" ",
140+
"$item.category"
141+
]
142+
}
143+
}
144+
}
145+
)
146+
147+
Because the document with ``_id`` equal to ``5`` is missing the
148+
``type`` field in the ``item`` sub-document,
149+
:expression:`$concat` returns the value ``null`` as the
150+
concatenated value for the document:
151+
152+
.. code-block:: javascript
153+
154+
{
155+
"result" : [
156+
{ "_id" : 1, "food" : "apple pie" },
157+
{ "_id" : 2, "food" : "cherry pie" },
158+
{ "_id" : 3, "food" : "shepherd's pie" },
159+
{ "_id" : 4, "food" : "chicken pot pie" },
160+
{ "_id" : 5, "food" : null }
161+
],
162+
"ok" : 1
163+
}
164+
165+
To handle possible missing fields, you can use
166+
:expression:`$ifNull` with :expression:`$concat`, as in the
167+
following example which substitutes ``<unknown type>`` if the
168+
field ``type`` is ``null`` or missing, and ``<unknown category>``
169+
if the field ``category`` is ``null`` or is missing:
170+
171+
.. code-block:: javascript
172+
173+
db.menu.aggregate( { $project: { food:
174+
{ $concat: [ { $ifNull: ["$item.type", "<unknown type>"] },
175+
" ",
176+
{ $ifNull: ["$item.category", "<unknown category>"] }
177+
]
178+
}
179+
}
180+
}
181+
)
182+
183+
The aggregation returns the following result set:
184+
185+
.. code-block:: javascript
186+
187+
{
188+
"result" : [
189+
{ "_id" : 1, "food" : "apple pie" },
190+
{ "_id" : 2, "food" : "cherry pie" },
191+
{ "_id" : 3, "food" : "shepherd's pie" },
192+
{ "_id" : 4, "food" : "chicken pot pie" },
193+
{ "_id" : 5, "food" : "coffee <unknown category>" }
194+
],
195+
"ok" : 1
196+
}

source/release-notes/2.4.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,3 +1442,11 @@ background at the same time. See :ref:`building indexes in the
14421442
background <index-creation-background>` for more information on
14431443
background index builds. Foreground index builds hold a database lock
14441444
and must proceed one at a time.
1445+
1446+
Aggregation Updates
1447+
~~~~~~~~~~~~~~~~~~~~
1448+
1449+
- Addition of :agg:expression:`$concat` to concatenate array of strings.
1450+
1451+
.. Need to merge this with other code-review updates regarding new agg
1452+
once they and this pass code review

0 commit comments

Comments
 (0)