@@ -47,8 +47,8 @@ The **aggregation pipeline** is the assembly line, **aggregation stages** are th
47
47
assembly stations, and **operator expressions** are the
48
48
specialized tools.
49
49
50
- Aggregation Versus Find Operations
51
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50
+ Compare Aggregation and Find Operations
51
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52
52
53
53
You can use find operations to perform the following actions:
54
54
@@ -72,6 +72,7 @@ Consider the following limitations when performing aggregation operations:
72
72
- Returned documents cannot violate the
73
73
:manual:`BSON document size limit </reference/limits/#mongodb-limit-BSON-Document-Size>`
74
74
of 16 megabytes.
75
+
75
76
- Pipeline stages have a memory limit of 100 megabytes by default. You can exceed this
76
77
limit by creating an options array that sets the ``allowDiskUse`` option to ``true``
77
78
and passing the array to the ``MongoDB\Collection::aggregate()`` method.
@@ -82,37 +83,63 @@ Consider the following limitations when performing aggregation operations:
82
83
</reference/operator/aggregation/graphLookup/>` stage has a strict
83
84
memory limit of 100 megabytes and ignores the ``allowDiskUse`` option.
84
85
85
- .. _php-aggregation-example:
86
+ Aggregation APIs
87
+ ----------------
86
88
87
- Aggregation Example
88
- -------------------
89
+ The {+library-short+} provides the following APIs to create aggregation
90
+ pipelines:
91
+
92
+ - :ref:`php-aggregation-array-api`: Create aggregation pipelines by
93
+ passing arrays that specify the aggregation stages.
94
+ - :ref:`php-aggregation-builder-api`: Create aggregation pipelines by
95
+ using factory methods to make your application more type-safe and debuggable.
96
+
97
+ The following sections describe each API and provide examples for
98
+ creating aggregation pipelines.
89
99
90
- .. note: :
100
+ .. _php-aggregation-array-api :
91
101
92
- The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants``
93
- database from the :atlas:`Atlas sample datasets </sample-data>`. To learn how to create a
94
- free MongoDB Atlas cluster and load the sample datasets, see the :atlas:`Get Started with Atlas
95
- </getting-started>` guide.
102
+ Array API
103
+ ---------
96
104
97
- To perform an aggregation, pass an array containing the pipeline stages to
98
- the ``MongoDB\Collection::aggregate()`` method.
105
+ To perform an aggregation, pass an array containing the pipeline stages
106
+ as BSON documents to the ``MongoDB\Collection::aggregate()`` method, as
107
+ shown in the following code:
108
+
109
+ .. code-block:: php
110
+
111
+ $pipeline = [
112
+ ['<stage>' => <parameters>],
113
+ ['<stage>' => <parameters>],
114
+ ...
115
+ ];
116
+
117
+ $cursor = $collection->aggregate($pipeline);
118
+
119
+ The examples in this section use the ``restaurants`` collection in the ``sample_restaurants``
120
+ database from the :atlas:`Atlas sample datasets </sample-data>`. To learn how to create a
121
+ free MongoDB Atlas cluster and load the sample datasets, see the :atlas:`Get Started with Atlas
122
+ </getting-started>` guide.
123
+
124
+ Filter and Group Example
125
+ ~~~~~~~~~~~~~~~~~~~~~~~~
99
126
100
127
The following code example produces a count of the number of bakeries in each borough
101
128
of New York. To do so, it uses an aggregation pipeline that contains the following stages:
102
129
103
- - :manual:`$match </reference/operator/aggregation/match/>` stage to filter for documents
104
- in which the ``cuisine`` field contains the value ``'Bakery'``
130
+ 1. :manual:`$match </reference/operator/aggregation/match/>` stage to filter for documents
131
+ in which the ``cuisine`` field contains the value ``'Bakery'``
105
132
106
- - :manual:`$group </reference/operator/aggregation/group/>` stage to group the matching
107
- documents by the ``borough`` field, accumulating a count of documents for each distinct
108
- value
133
+ #. :manual:`$group </reference/operator/aggregation/group/>` stage to group the matching
134
+ documents by the ``borough`` field, accumulating a count of documents for each distinct
135
+ value
109
136
110
137
.. io-code-block::
111
138
:copyable:
112
139
113
140
.. input:: /includes/aggregation/aggregation.php
114
- :start-after: start-match-group
115
- :end-before: end-match-group
141
+ :start-after: start-array- match-group
142
+ :end-before: end-array- match-group
116
143
:language: php
117
144
:dedent:
118
145
@@ -141,14 +168,14 @@ and pass the database, collection, and pipeline stages as parameters. Then, pass
141
168
``MongoDB\Operation\Aggregate`` object to the ``MongoDB\Collection::explain()`` method.
142
169
143
170
The following example instructs MongoDB to explain the aggregation operation
144
- from the preceding :ref:`php-aggregation-example` :
171
+ from the preceding section :
145
172
146
173
.. io-code-block::
147
174
:copyable:
148
175
149
176
.. input:: /includes/aggregation/aggregation.php
150
- :start-after: start-explain
151
- :end-before: end-explain
177
+ :start-after: start-array- explain
178
+ :end-before: end-array- explain
152
179
:language: php
153
180
:dedent:
154
181
@@ -161,6 +188,158 @@ from the preceding :ref:`php-aggregation-example`:
161
188
"maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{
162
189
... }
163
190
191
+ .. _php-aggregation-builder-api:
192
+
193
+ Aggregation Builder
194
+ -------------------
195
+
196
+ To create an aggregation pipeline by using the Aggregation Builder,
197
+ perform the following actions:
198
+
199
+ 1. Create an array to store the pipeline stages.
200
+
201
+ #. For each stage, call the a factory method from the
202
+ ``Stage`` that shares the same name as your desired aggregation
203
+ stage. For example, to create an ``$unwind`` stage, call the
204
+ ``Stage::unwind()`` method.
205
+
206
+ #. Within the body of the ``Stage`` method, use methods from other
207
+ builder classes such as ``Query``, ``Expression``, or ``Accumulator``
208
+ to express your aggregation specifications.
209
+
210
+ The following code demonstrates the template for constructing
211
+ aggregation pipelines:
212
+
213
+ .. code-block:: php
214
+
215
+ $pipeline = [
216
+ Stage::<factory method>(
217
+ <stage specification>
218
+ ),
219
+ Stage::<factory method>(
220
+ <stage specification>
221
+ ),
222
+ ...
223
+ ];
224
+
225
+ $cursor = $collection->aggregate($pipeline);
226
+
227
+ The examples in this section are adapted from the {+mdb-server+} manual.
228
+ Each example provides a link to the sample data that you can insert into
229
+ your database to test the aggregation operation.
230
+
231
+ Filter and Group Example
232
+ ~~~~~~~~~~~~~~~~~~~~~~~~
233
+
234
+ This example uses the sample data given in the :manual:`Calculate Count,
235
+ Sum, and Average </reference/operator/aggregation/group/#calculate-count--sum--and-average>`
236
+ section of the ``$group`` stage reference in the Server manual.
237
+
238
+ The following code example calculates the total sales amount, average
239
+ sales quantity, and sale count for each day in the year 2014. To do so,
240
+ it uses an aggregation pipeline that contains the following stages:
241
+
242
+ 1. :manual:`$match </reference/operator/aggregation/match/>` stage to
243
+ filter for documents that contain a ``date`` field in which the year is
244
+ 2014
245
+
246
+ #. :manual:`$group </reference/operator/aggregation/group/>` stage to
247
+ group the documents by date and calculate the total sales amount,
248
+ average sales quantity, and sale count for each group
249
+
250
+ #. :manual:`$sort </reference/operator/aggregation/sort/>` stage to
251
+ sort the results by the total sale amount for each group in descending
252
+ order
253
+
254
+ .. io-code-block::
255
+ :copyable:
256
+
257
+ .. input:: /includes/aggregation/aggregation.php
258
+ :start-after: start-builder-match-group
259
+ :end-before: end-builder-match-group
260
+ :language: php
261
+ :dedent:
262
+
263
+ .. output::
264
+ :visible: false
265
+
266
+ {"_id":"2014-04-04","totalSaleAmount":{"$numberDecimal":"200"},"averageQuantity":15,"count":2}
267
+ {"_id":"2014-03-15","totalSaleAmount":{"$numberDecimal":"50"},"averageQuantity":10,"count":1}
268
+ {"_id":"2014-03-01","totalSaleAmount":{"$numberDecimal":"40"},"averageQuantity":1.5,"count":2}
269
+
270
+ Unwind Embedded Arrays Example
271
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
272
+
273
+ This example uses the sample data given in the :manual:`Unwind Embedded Arrays
274
+ </reference/operator/aggregation/unwind/#unwind-embedded-arrays>`
275
+ section of the ``$unwind`` stage reference in the Server manual.
276
+
277
+ The following code example groups sold items by their tags and
278
+ calculates the total sales amount for each tag. To do so,
279
+ it uses an aggregation pipeline that contains the following stages:
280
+
281
+ 1. :manual:`$unwind </reference/operator/aggregation/unwind/>` stage to
282
+ output a separate document for each element in the ``items`` array
283
+
284
+ #. :manual:`$unwind </reference/operator/aggregation/unwind/>` stage to
285
+ output a separate document for each element in the ``items.tags`` arrays
286
+
287
+ #. :manual:`$group </reference/operator/aggregation/group/>` stage to
288
+ group the documents by the tag value and calculate the total sales
289
+ amount of items that have each tag
290
+
291
+ .. io-code-block::
292
+ :copyable:
293
+
294
+ .. input:: /includes/aggregation/aggregation.php
295
+ :start-after: start-builder-unwind
296
+ :end-before: end-builder-unwind
297
+ :language: php
298
+ :dedent:
299
+
300
+ .. output::
301
+ :visible: false
302
+
303
+ {"_id":"office","totalSalesAmount":{"$numberDecimal":"1019.60"}}
304
+ {"_id":"school","totalSalesAmount":{"$numberDecimal":"104.85"}}
305
+ {"_id":"stationary","totalSalesAmount":{"$numberDecimal":"264.45"}}
306
+ {"_id":"electronics","totalSalesAmount":{"$numberDecimal":"800.00"}}
307
+ {"_id":"writing","totalSalesAmount":{"$numberDecimal":"60.00"}}
308
+
309
+ Single Equality Join Example
310
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311
+
312
+ This example uses the sample data given in the :manual:`Perform a Single
313
+ Equality Join with $lookup
314
+ </reference/operator/aggregation/lookup/#perform-a-single-equality-join-with--lookup>`
315
+ section of the ``$lookup`` stage reference in the Server manual.
316
+
317
+ The following code example joins the documents from the ``orders``
318
+ collection with the documents from the ``inventory`` collection by using
319
+ the ``item`` field from the ``orders`` collection and the ``sku`` field
320
+ from the ``inventory`` collection.
321
+
322
+ To do so, the example uses an aggregation pipeline that contains a
323
+ :manual:`$lookup </reference/operator/aggregation/lookup/>` stage that
324
+ specifies the collection to retrieve data from and the local and
325
+ foreign field names.
326
+
327
+ .. io-code-block::
328
+ :copyable:
329
+
330
+ .. input:: /includes/aggregation/aggregation.php
331
+ :start-after: start-builder-lookup
332
+ :end-before: end-builder-lookup
333
+ :language: php
334
+ :dedent:
335
+
336
+ .. output::
337
+ :visible: false
338
+
339
+ {"_id":1,"item":"almonds","price":12,"quantity":2,"inventory_docs":[{"_id":1,"sku":"almonds","description":"product 1","instock":120}]}
340
+ {"_id":2,"item":"pecans","price":20,"quantity":1,"inventory_docs":[{"_id":4,"sku":"pecans","description":"product 4","instock":70}]}
341
+ {"_id":3,"inventory_docs":[{"_id":5,"sku":null,"description":"Incomplete"},{"_id":6}]}
342
+
164
343
Additional Information
165
344
----------------------
166
345
@@ -169,6 +348,11 @@ pipelines, see `Complex Aggregation Pipelines with Vanilla PHP and MongoDB
169
348
<https://www.mongodb.com/developer/products/mongodb/aggregations-php-mongodb/>`__
170
349
in the MongoDB Developer Center.
171
350
351
+ To view more examples of aggregation pipelines built by using the Aggregation
352
+ Builder, see the :github:`Stage class test suite
353
+ <mongodb/mongo-php-library/tree/{+source-gh-branch+}/tests/Builder/Stage>` in the
354
+ {+library-short+} source code on GitHub.
355
+
172
356
MongoDB Server Manual
173
357
~~~~~~~~~~~~~~~~~~~~~
174
358
0 commit comments