@@ -47,8 +47,8 @@ The **aggregation pipeline** is the assembly line, **aggregation stages** are th
4747assembly stations, and **operator expressions** are the
4848specialized tools.
4949
50- Aggregation Versus Find Operations
51- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50+ Compare Aggregation and Find Operations
51+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5252
5353You can use find operations to perform the following actions:
5454
@@ -72,6 +72,7 @@ Consider the following limitations when performing aggregation operations:
7272- Returned documents cannot violate the
7373 :manual:`BSON document size limit </reference/limits/#mongodb-limit-BSON-Document-Size>`
7474 of 16 megabytes.
75+
7576- Pipeline stages have a memory limit of 100 megabytes by default. You can exceed this
7677 limit by creating an options array that sets the ``allowDiskUse`` option to ``true``
7778 and passing the array to the ``MongoDB\Collection::aggregate()`` method.
@@ -82,37 +83,63 @@ Consider the following limitations when performing aggregation operations:
8283 </reference/operator/aggregation/graphLookup/>` stage has a strict
8384 memory limit of 100 megabytes and ignores the ``allowDiskUse`` option.
8485
85- .. _php-aggregation-example:
86+ Aggregation APIs
87+ ----------------
8688
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.
8999
90- .. note: :
100+ .. _php-aggregation-array-api :
91101
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+ ---------
96104
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+ ~~~~~~~~~~~~~~~~~~~~~~~~
99126
100127The following code example produces a count of the number of bakeries in each borough
101128of New York. To do so, it uses an aggregation pipeline that contains the following stages:
102129
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'``
105132
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
109136
110137.. io-code-block::
111138 :copyable:
112139
113140 .. 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
116143 :language: php
117144 :dedent:
118145
@@ -141,14 +168,14 @@ and pass the database, collection, and pipeline stages as parameters. Then, pass
141168``MongoDB\Operation\Aggregate`` object to the ``MongoDB\Collection::explain()`` method.
142169
143170The following example instructs MongoDB to explain the aggregation operation
144- from the preceding :ref:`php-aggregation-example` :
171+ from the preceding section :
145172
146173.. io-code-block::
147174 :copyable:
148175
149176 .. 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
152179 :language: php
153180 :dedent:
154181
@@ -161,6 +188,158 @@ from the preceding :ref:`php-aggregation-example`:
161188 "maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{
162189 ... }
163190
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+
164343Additional Information
165344----------------------
166345
@@ -169,6 +348,11 @@ pipelines, see `Complex Aggregation Pipelines with Vanilla PHP and MongoDB
169348<https://www.mongodb.com/developer/products/mongodb/aggregations-php-mongodb/>`__
170349in the MongoDB Developer Center.
171350
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+
172356MongoDB Server Manual
173357~~~~~~~~~~~~~~~~~~~~~
174358
0 commit comments