Skip to content

Commit 40ab0e3

Browse files
committed
DOCSP-43919: aggregation builder
1 parent 150d78d commit 40ab0e3

File tree

4 files changed

+308
-35
lines changed

4 files changed

+308
-35
lines changed

snooty.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ php-library = "MongoDB PHP Library"
4040
[constants]
4141
php-library = "MongoDB PHP Library"
4242
version = "1.20"
43+
source-gh-branch = "v1.x"
4344
full-version = "{+version+}.0"
4445
extension-short = "PHP extension"
4546
mdb-server = "MongoDB Server"

source/aggregation.txt

+209-23
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ Transform Your Data with Aggregation
1818
:depth: 2
1919
:class: singlecol
2020

21-
.. TODO:
22-
.. toctree::
23-
:titlesonly:
24-
:maxdepth: 1
25-
26-
/aggregation/aggregation-tutorials
21+
.. .. toctree::
22+
.. :titlesonly:
23+
.. :maxdepth: 1
24+
..
25+
.. /aggregation/aggregation-tutorials
2726

2827
Overview
2928
--------
@@ -47,8 +46,8 @@ The **aggregation pipeline** is the assembly line, **aggregation stages** are th
4746
assembly stations, and **operator expressions** are the
4847
specialized tools.
4948

50-
Aggregation Versus Find Operations
51-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49+
Compare Aggregation and Find Operations
50+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5251

5352
You can use find operations to perform the following actions:
5453

@@ -82,20 +81,46 @@ Consider the following limitations when performing aggregation operations:
8281
</reference/operator/aggregation/graphLookup/>` stage has a strict
8382
memory limit of 100 megabytes and ignores the ``allowDiskUse`` option.
8483

85-
.. _php-aggregation-example:
84+
Aggregation APIs
85+
----------------
8686

87-
Aggregation Example
88-
-------------------
87+
The {+library-short+} provides the following APIs to create aggregation
88+
pipelines:
8989

90-
.. note::
90+
- :ref:`php-aggregation-array-api`: Create aggregation pipelines by
91+
passing arrays that specify the aggregation operators and parameters
92+
- :ref:`php-aggregation-builder-api`: Create aggregation pipelines by using native
93+
classes and methods to make your application more type-safe and debuggable
94+
95+
The following sections describe each API and provide examples for
96+
creating aggregation pipelines.
97+
98+
.. _php-aggregation-array-api:
99+
100+
Array API
101+
---------
102+
103+
To perform an aggregation, pass an array containing the pipeline stages
104+
as BSON documents to the ``MongoDB\Collection::aggregate()`` method, as
105+
shown in the following code:
106+
107+
.. code-block:: php
108+
109+
$pipeline = [
110+
['<operator>' => <parameters>],
111+
['<operator>' => <parameters>],
112+
...
113+
];
114+
115+
$cursor = $collection->aggregate($pipeline);
91116

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.
117+
The examples in this section use the ``restaurants`` collection in the ``sample_restaurants``
118+
database from the :atlas:`Atlas sample datasets </sample-data>`. To learn how to create a
119+
free MongoDB Atlas cluster and load the sample datasets, see the :atlas:`Get Started with Atlas
120+
</getting-started>` guide.
96121

97-
To perform an aggregation, pass an array containing the pipeline stages to
98-
the ``MongoDB\Collection::aggregate()`` method.
122+
Filter and Group Example
123+
~~~~~~~~~~~~~~~~~~~~~~~~
99124

100125
The following code example produces a count of the number of bakeries in each borough
101126
of New York. To do so, it uses an aggregation pipeline that contains the following stages:
@@ -111,8 +136,8 @@ of New York. To do so, it uses an aggregation pipeline that contains the followi
111136
:copyable:
112137

113138
.. input:: /includes/aggregation.php
114-
:start-after: start-match-group
115-
:end-before: end-match-group
139+
:start-after: start-array-match-group
140+
:end-before: end-array-match-group
116141
:language: php
117142
:dedent:
118143

@@ -141,14 +166,14 @@ and pass the database, collection, and pipeline stages as parameters. Then, pass
141166
``MongoDB\Operation\Aggregate`` object to the ``MongoDB\Collection::explain()`` method.
142167

143168
The following example instructs MongoDB to explain the aggregation operation
144-
from the preceding :ref:`php-aggregation-example`:
169+
from the preceding section:
145170

146171
.. io-code-block::
147172
:copyable:
148173

149174
.. input:: /includes/aggregation.php
150-
:start-after: start-explain
151-
:end-before: end-explain
175+
:start-after: start-array-explain
176+
:end-before: end-array-explain
152177
:language: php
153178
:dedent:
154179

@@ -161,6 +186,162 @@ from the preceding :ref:`php-aggregation-example`:
161186
"maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{
162187
... }
163188

189+
.. _php-aggregation-builder-api:
190+
191+
Aggregation Builder
192+
-------------------
193+
194+
To create an aggregation pipeline by using the Aggregation Builder,
195+
perform the following actions:
196+
197+
#. Create a ``Pipeline`` class instance to initialize the pipeline
198+
199+
#. Within the ``Pipeline`` instance, call an operator method from the ``Stage``
200+
builder class to create that type of aggregation stage
201+
202+
#. Within the body of the ``Stage`` method, use methods from other
203+
builder classes such as ``Query``, ``Expression``, or ``Accumulator``
204+
to express your aggregation specifications
205+
206+
The following code demonstrates the template for constructing
207+
aggregation pipelines:
208+
209+
.. code-block:: php
210+
211+
$pipeline = new Pipeline(
212+
Stage::<operator method>(
213+
<stage specification>
214+
),
215+
Stage::<operator method>(
216+
<stage specification>
217+
),
218+
...
219+
);
220+
221+
$cursor = $collection->aggregate(iterator_to_array($pipeline));
222+
223+
.. note::
224+
225+
The preceding code uses the ``iterator_to_array()`` method to
226+
convert the ``Pipeline`` instance into an array. You must call this method
227+
on your ``Pipeline`` before passing it to the ``aggregate()`` method.
228+
229+
The examples in this section are adapted from the {+mdb-server+} manual.
230+
Each example provides a link to the sample data that you can insert into
231+
your database to test the aggregation operation.
232+
233+
Filter and Group Example
234+
~~~~~~~~~~~~~~~~~~~~~~~~
235+
236+
This example uses the sample data given in the :manual:`Calculate Count,
237+
Sum, and Average </reference/operator/aggregation/group/#calculate-count--sum--and-average>`
238+
section of the ``$group`` stage reference in the Server manual.
239+
240+
The following code example calculates the total sales amount, average
241+
sales quantity, and sale count for each day in the year 2014. To do so,
242+
it uses an aggregation pipeline that contains the following stages:
243+
244+
- :manual:`$match </reference/operator/aggregation/match/>` stage to
245+
filter for documents that contain a ``date`` field in which the year is
246+
2014
247+
248+
- :manual:`$group </reference/operator/aggregation/group/>` stage to
249+
group the documents by date and calculate the total sale amount,
250+
average quantity, and total count for each group
251+
252+
- :manual:`$sort </reference/operator/aggregation/sort/>` stage to
253+
sort the results by the total sale amount for each group in descending
254+
order
255+
256+
.. io-code-block::
257+
:copyable:
258+
259+
.. input:: /includes/aggregation.php
260+
:start-after: start-builder-match-group
261+
:end-before: end-builder-match-group
262+
:language: php
263+
:dedent:
264+
265+
.. output::
266+
:visible: false
267+
268+
{"_id":"2014-04-04","totalSaleAmount":{"$numberDecimal":"200"},"averageQuantity":15,"count":2}
269+
{"_id":"2014-03-15","totalSaleAmount":{"$numberDecimal":"50"},"averageQuantity":10,"count":1}
270+
{"_id":"2014-03-01","totalSaleAmount":{"$numberDecimal":"40"},"averageQuantity":1.5,"count":2}
271+
272+
Unwind Embedded Arrays Example
273+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
274+
275+
This example uses the sample data given in the :manual:`Unwind Embedded Arrays
276+
</reference/operator/aggregation/unwind/#unwind-embedded-arrays>`
277+
section of the ``$unwind`` stage reference in the Server manual.
278+
279+
The following code example groups sold items by their tags and
280+
calculates the total sales amount for each tag. To do so,
281+
it uses an aggregation pipeline that contains the following stages:
282+
283+
- :manual:`$unwind </reference/operator/aggregation/unwind/>` stage to
284+
output a separate document for each element in the ``items`` array
285+
286+
- :manual:`$unwind </reference/operator/aggregation/unwind/>` stage to
287+
output a separate document for each element in the ``items.tags`` arrays
288+
289+
- :manual:`$group </reference/operator/aggregation/group/>` stage to
290+
group the documents by the tag value and calculates the total sales
291+
amount of items that have each tag
292+
293+
.. io-code-block::
294+
:copyable:
295+
296+
.. input:: /includes/aggregation.php
297+
:start-after: start-builder-unwind
298+
:end-before: end-builder-unwind
299+
:language: php
300+
:dedent:
301+
302+
.. output::
303+
:visible: false
304+
305+
{"_id":"office","totalSalesAmount":{"$numberDecimal":"1019.60"}}
306+
{"_id":"school","totalSalesAmount":{"$numberDecimal":"104.85"}}
307+
{"_id":"stationary","totalSalesAmount":{"$numberDecimal":"264.45"}}
308+
{"_id":"electronics","totalSalesAmount":{"$numberDecimal":"800.00"}}
309+
{"_id":"writing","totalSalesAmount":{"$numberDecimal":"60.00"}}
310+
311+
Single Equality Join Example
312+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
313+
314+
This example uses the sample data given in the :manual:`Perform a Single
315+
Equality Join with $lookup
316+
</reference/operator/aggregation/lookup/#perform-a-single-equality-join-with--lookup>`
317+
section of the ``$lookup`` stage reference in the Server manual.
318+
319+
The following code example joins the documents from the ``orders``
320+
collection with the documents from the ``inventory`` collection by using
321+
the ``item`` field from the ``orders`` collection and the ``sku`` field
322+
from the ``inventory`` collection.
323+
324+
To do so, the example uses an aggregation pipeline that contains a
325+
:manual:`$lookup </reference/operator/aggregation/lookup/>` stage that
326+
specifies the collection to retrieve data from and the local and
327+
foreign field names.
328+
329+
.. io-code-block::
330+
:copyable:
331+
332+
.. input:: /includes/aggregation.php
333+
:start-after: start-builder-lookup
334+
:end-before: end-builder-lookup
335+
:language: php
336+
:dedent:
337+
338+
.. output::
339+
:visible: false
340+
341+
{"_id":1,"item":"almonds","price":12,"quantity":2,"inventory_docs":[{"_id":1,"sku":"almonds","description":"product 1","instock":120}]}
342+
{"_id":2,"item":"pecans","price":20,"quantity":1,"inventory_docs":[{"_id":4,"sku":"pecans","description":"product 4","instock":70}]}
343+
{"_id":3,"inventory_docs":[{"_id":5,"sku":null,"description":"Incomplete"},{"_id":6}]}
344+
164345
Additional Information
165346
----------------------
166347

@@ -169,6 +350,11 @@ pipelines, see `Complex Aggregation Pipelines with Vanilla PHP and MongoDB
169350
<https://www.mongodb.com/developer/products/mongodb/aggregations-php-mongodb/>`__
170351
in the MongoDB Developer Center.
171352

353+
To view more examples of aggregation pipelines built by using the Aggregation
354+
Builder, see the :github:`Stage class test suite
355+
<mongodb/mongo-php-library/tree/{+source-gh-branch+}/tests/Builder/Stage>` in the
356+
{+library-short+} source code on GitHub.
357+
172358
MongoDB Server Manual
173359
~~~~~~~~~~~~~~~~~~~~~
174360

0 commit comments

Comments
 (0)