Skip to content

Commit d9029d7

Browse files
author
Sam Kleinman
committed
merge: aggregation concat operator
2 parents 451f6ee + 4d83043 commit d9029d7

File tree

3 files changed

+204
-3
lines changed

3 files changed

+204
-3
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: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ JavaScript Engine Changed to V8
419419

420420
/release-notes/2.4-javascript
421421

422-
423422
In 2.4 the default JavaScript engine in the :program:`mongo` shell
424423
:program:`mongod` is now V8. This change affects all JavaScript
425424
behavior including the :dbcommand:`mapReduce`, :dbcommand:`group`, and
@@ -452,7 +451,9 @@ Additional Limitations for Map-Reduce and ``$where`` Operations
452451
Improvements to the Aggregation Framework
453452
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
454453

455-
- :agg:pipeline:`$match` queries support the :operator:`$within` operator.
454+
- :agg:pipeline:`$match` queries now support the :operator:`$within` operator.
456455

457-
- New :agg:expression:`$millisecond` operator to return the millisecond
456+
- New :agg:expression:`$millisecond` operator returns the millisecond
458457
portion of a date.
458+
459+
- New :agg:expression:`$concat` concatenates array of strings.

0 commit comments

Comments
 (0)