Skip to content

Commit f7d2584

Browse files
authored
DOCSP-41988: Aggregation (#115)
* DOCSP-41988: Aggregation * toc * edits * code edit * JS feedback * dev center * JM feedback * explain api link * JM feedback 2
1 parent a4b3796 commit f7d2584

File tree

7 files changed

+263
-17
lines changed

7 files changed

+263
-17
lines changed

source/aggregation.txt

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
.. _php-aggregation:
2+
3+
====================================
4+
Transform Your Data with Aggregation
5+
====================================
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: code example, transform, computed, pipeline
13+
:description: Learn how to use the PHP library to perform aggregation operations.
14+
15+
.. contents:: On this page
16+
:local:
17+
:backlinks: none
18+
:depth: 2
19+
:class: singlecol
20+
21+
.. TODO:
22+
.. toctree::
23+
:titlesonly:
24+
:maxdepth: 1
25+
26+
/aggregation/aggregation-tutorials
27+
28+
Overview
29+
--------
30+
31+
In this guide, you can learn how to use the {+php-library+} to perform
32+
**aggregation operations**.
33+
34+
Aggregation operations process data in your MongoDB collections and
35+
return computed results. The MongoDB Aggregation framework, which is
36+
part of the Query API, is modeled on the concept of data processing
37+
pipelines. Documents enter a pipeline that contains one or more stages,
38+
and this pipeline transforms the documents into an aggregated result.
39+
40+
An aggregation operation is similar to a car factory. A car factory has
41+
an assembly line, which contains assembly stations with specialized
42+
tools to do specific jobs, like drills and welders. Raw parts enter the
43+
factory, and then the assembly line transforms and assembles them into a
44+
finished product.
45+
46+
The **aggregation pipeline** is the assembly line, **aggregation stages** are the
47+
assembly stations, and **operator expressions** are the
48+
specialized tools.
49+
50+
Aggregation Versus Find Operations
51+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52+
53+
You can use find operations to perform the following actions:
54+
55+
- Select which documents to return
56+
- Select which fields to return
57+
- Sort the results
58+
59+
You can use aggregation operations to perform the following actions:
60+
61+
- Run find operations
62+
- Rename fields
63+
- Calculate fields
64+
- Summarize data
65+
- Group values
66+
67+
Limitations
68+
~~~~~~~~~~~
69+
70+
Consider the following limitations when performing aggregation operations:
71+
72+
- Returned documents cannot violate the
73+
:manual:`BSON document size limit </reference/limits/#mongodb-limit-BSON-Document-Size>`
74+
of 16 megabytes.
75+
- Pipeline stages have a memory limit of 100 megabytes by default. You can exceed this
76+
limit by creating an options array that sets the ``allowDiskUse`` option to ``true``
77+
and passing the array to the ``MongoDB\Collection::aggregate()`` method.
78+
79+
.. important:: $graphLookup Exception
80+
81+
The :manual:`$graphLookup
82+
</reference/operator/aggregation/graphLookup/>` stage has a strict
83+
memory limit of 100 megabytes and ignores the ``allowDiskUse`` option.
84+
85+
.. _php-aggregation-example:
86+
87+
Aggregation Example
88+
-------------------
89+
90+
.. note::
91+
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.
96+
97+
To perform an aggregation, pass an array containing the pipeline stages to
98+
the ``MongoDB\Collection::aggregate()`` method.
99+
100+
The following code example produces a count of the number of bakeries in each borough
101+
of New York. To do so, it uses an aggregation pipeline that contains the following stages:
102+
103+
- :manual:`$match </reference/operator/aggregation/match/>` stage to filter for documents
104+
in which the ``cuisine`` field contains the value ``'Bakery'``
105+
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
109+
110+
.. io-code-block::
111+
:copyable:
112+
113+
.. input:: /includes/aggregation.php
114+
:start-after: start-match-group
115+
:end-before: end-match-group
116+
:language: php
117+
:dedent:
118+
119+
.. output::
120+
:visible: false
121+
122+
{"_id":"Brooklyn","count":173}
123+
{"_id":"Queens","count":204}
124+
{"_id":"Bronx","count":71}
125+
{"_id":"Staten Island","count":20}
126+
{"_id":"Missing","count":2}
127+
{"_id":"Manhattan","count":221}
128+
129+
Explain an Aggregation
130+
~~~~~~~~~~~~~~~~~~~~~~
131+
132+
To view information about how MongoDB executes your operation, you can
133+
instruct the MongoDB query planner to **explain** it. When MongoDB explains
134+
an operation, it returns **execution plans** and performance statistics.
135+
An execution plan is a potential way in which MongoDB can complete an operation.
136+
When you instruct MongoDB to explain an operation, it returns both the
137+
plan MongoDB executed and any rejected execution plans.
138+
139+
To explain an aggregation operation, construct a ``MongoDB\Operation\Aggregate`` object
140+
and pass the database, collection, and pipeline stages as parameters. Then, pass the
141+
``MongoDB\Operation\Aggregate`` object to the ``MongoDB\Collection::explain()`` method.
142+
143+
The following example instructs MongoDB to explain the aggregation operation
144+
from the preceding :ref:`php-aggregation-example`:
145+
146+
.. io-code-block::
147+
:copyable:
148+
149+
.. input:: /includes/aggregation.php
150+
:start-after: start-explain
151+
:end-before: end-explain
152+
:language: php
153+
:dedent:
154+
155+
.. output::
156+
:visible: false
157+
158+
{"explainVersion":"2","queryPlanner":{"namespace":"sample_restaurants.restaurants",
159+
"indexFilterSet":false,"parsedQuery":{"cuisine":{"$eq":"Bakery"}},"queryHash":"865F14C3",
160+
"planCacheKey":"D56D6F10","optimizedPipeline":true,"maxIndexedOrSolutionsReached":false,
161+
"maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{
162+
... }
163+
164+
Additional Information
165+
----------------------
166+
167+
To view a tutorial that uses the {+php-library+} to create complex aggregation
168+
pipelines, see `Complex Aggregation Pipelines with Vanilla PHP and MongoDB
169+
<https://www.mongodb.com/developer/products/mongodb/aggregations-php-mongodb/>`__
170+
in the MongoDB Developer Center.
171+
172+
MongoDB Server Manual
173+
~~~~~~~~~~~~~~~~~~~~~
174+
175+
To learn more about the topics discussed in this guide, see the following
176+
pages in the {+mdb-server+} manual:
177+
178+
- To view a full list of expression operators, see :manual:`Aggregation
179+
Operators </reference/operator/aggregation/>`.
180+
181+
- To learn about assembling an aggregation pipeline and to view examples, see
182+
:manual:`Aggregation Pipeline </core/aggregation-pipeline/>`.
183+
184+
- To learn more about creating pipeline stages, see :manual:`Aggregation
185+
Stages </reference/operator/aggregation-pipeline/>`.
186+
187+
- To learn more about explaining MongoDB operations, see
188+
:manual:`Explain Output </reference/explain-results/>` and
189+
:manual:`Query Plans </core/query-plans/>`.
190+
191+
.. TODO:
192+
Aggregation Tutorials
193+
~~~~~~~~~~~~~~~~~~~~~
194+
195+
.. To view step-by-step explanations of common aggregation tasks, see
196+
.. :ref:`php-aggregation-tutorials-landing`.
197+
198+
API Documentation
199+
~~~~~~~~~~~~~~~~~
200+
201+
To learn more about the methods discussed in this guide, see the
202+
following API documentation:
203+
204+
- `MongoDB\\Collection::aggregate() <{+api+}/method/MongoDBCollection-aggregate/>`__
205+
- `MongoDB\\Collection::explain() <{+api+}/method/MongoDBCollection-explain/>`__

source/includes/aggregation.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
require 'vendor/autoload.php';
3+
4+
$uri = getenv('MONGODB_URI') ?: throw new RuntimeException('Set the MONGODB_URI variable to your Atlas URI that connects to the sample dataset');
5+
$client = new MongoDB\Client($uri);
6+
7+
$collection = $client->sample_restaurants->restaurants;
8+
9+
// Retrieves documents with a cuisine value of "Bakery", groups them by "borough", and
10+
// counts each borough's matching documents
11+
// start-match-group
12+
$pipeline = [
13+
['$match' => ['cuisine' => 'Bakery']],
14+
['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]],
15+
];
16+
17+
$cursor = $collection->aggregate($pipeline);
18+
19+
foreach ($cursor as $doc) {
20+
echo json_encode($doc) , PHP_EOL;
21+
}
22+
// end-match-group
23+
24+
// Performs the same aggregation operation as above but asks MongoDB to explain it
25+
// start-explain
26+
$pipeline = [
27+
['$match' => ['cuisine' => 'Bakery']],
28+
['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]],
29+
];
30+
31+
$aggregate = new MongoDB\Operation\Aggregate(
32+
$collection->getDatabaseName(),
33+
$collection->getCollectionName(),
34+
$pipeline
35+
);
36+
37+
$result = $collection->explain($aggregate);
38+
echo json_encode($result) , PHP_EOL;
39+
// end-explain
40+

source/includes/read/limit-skip-sort.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
);
1818

1919
foreach ($cursor as $doc) {
20-
echo json_encode($doc) . PHP_EOL;
20+
echo json_encode($doc) , PHP_EOL;
2121
}
2222
// end-limit
2323

@@ -29,7 +29,7 @@
2929
);
3030

3131
foreach ($cursor as $doc) {
32-
echo json_encode($doc) . PHP_EOL;
32+
echo json_encode($doc) , PHP_EOL;
3333
}
3434
// end-sort
3535

@@ -41,7 +41,7 @@
4141
);
4242

4343
foreach ($cursor as $doc) {
44-
echo json_encode($doc) . PHP_EOL;
44+
echo json_encode($doc) , PHP_EOL;
4545
}
4646
// end-skip
4747

@@ -56,7 +56,7 @@
5656

5757
$cursor = $collection->find(['cuisine' => 'Italian'], $options);
5858
foreach ($cursor as $doc) {
59-
echo json_encode($doc) . PHP_EOL;
59+
echo json_encode($doc) , PHP_EOL;
6060
}
6161
// end-limit-sort-skip
6262

source/includes/read/project.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
$cursor = $collection->find(['name' => 'Emerald Pub'], $options);
2323
foreach ($cursor as $doc) {
24-
echo json_encode($doc) . PHP_EOL;
24+
echo json_encode($doc) , PHP_EOL;
2525
}
2626
// end-project-include
2727

@@ -39,7 +39,7 @@
3939

4040
$cursor = $collection->find(['name' => 'Emerald Pub'], $options);
4141
foreach ($cursor as $doc) {
42-
echo json_encode($doc) . PHP_EOL;
42+
echo json_encode($doc) , PHP_EOL;
4343
}
4444
// end-project-include-without-id
4545

@@ -54,6 +54,6 @@
5454

5555
$cursor = $collection->find(['name' => 'Emerald Pub'], $options);
5656
foreach ($cursor as $doc) {
57-
echo json_encode($doc) . PHP_EOL;
57+
echo json_encode($doc) , PHP_EOL;
5858
}
5959
// end-project-exclude

source/includes/read/retrieve.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// Finds one document with a "name" value of "LinkedIn"
1212
// start-find-one
1313
$document = $collection->findOne(['name' => 'LinkedIn']);
14-
echo json_encode($document) . "\n";
14+
echo json_encode($document) , "\n";
1515
// end-find-one
1616

1717
// Finds documents with a "founded_year" value of 1970
@@ -22,7 +22,7 @@
2222
// Prints documents with a "founded_year" value of 1970
2323
// start-cursor
2424
foreach ($results as $doc) {
25-
echo json_encode($doc) . "\n";
25+
echo json_encode($doc) , "\n";
2626
}
2727
// end-cursor
2828

@@ -34,6 +34,6 @@
3434
);
3535

3636
foreach ($results as $doc) {
37-
echo json_encode($doc) . "\n";
37+
echo json_encode($doc) , "\n";
3838
}
3939
// end-modify

source/includes/read/specify-queries.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,23 @@
5050
// start-find-exact
5151
$cursor = $collection->find(['color' => 'yellow']);
5252
foreach ($cursor as $doc) {
53-
echo json_encode($doc) . PHP_EOL;
53+
echo json_encode($doc) , PHP_EOL;
5454
}
5555
// end-find-exact
5656

5757
// Retrieves all documents in the collection
5858
// start-find-all
5959
$cursor = $collection->find([]);
6060
foreach ($cursor as $doc) {
61-
echo json_encode($doc) . PHP_EOL;
61+
echo json_encode($doc) , PHP_EOL;
6262
}
6363
// end-find-all
6464

6565
// Retrieves and prints documents in which the "rating" value is greater than 2
6666
// start-find-comparison
6767
$cursor = $collection->find(['rating' => ['$gt' => 2]]);
6868
foreach ($cursor as $doc) {
69-
echo json_encode($doc) . PHP_EOL;
69+
echo json_encode($doc) , PHP_EOL;
7070
}
7171
// end-find-comparison
7272

@@ -79,30 +79,30 @@
7979
]
8080
]);
8181
foreach ($cursor as $doc) {
82-
echo json_encode($doc) . PHP_EOL;
82+
echo json_encode($doc) , PHP_EOL;
8383
}
8484
// end-find-logical
8585

8686
// Retrieves and prints documents in which the "type" array has 2 elements
8787
// start-find-array
8888
$cursor = $collection->find(['type' => ['$size' => 2]]);
8989
foreach ($cursor as $doc) {
90-
echo json_encode($doc) . PHP_EOL;
90+
echo json_encode($doc) , PHP_EOL;
9191
}
9292
// end-find-array
9393

9494
// Retrieves and prints documents that have a "color" field
9595
// start-find-element
9696
$cursor = $collection->find(['color' => ['$exists' => true]]);
9797
foreach ($cursor as $doc) {
98-
echo json_encode($doc) . PHP_EOL;
98+
echo json_encode($doc) , PHP_EOL;
9999
}
100100
// end-find-element
101101

102102
// Retrieves and prints documents in which the "name" value has at least two consecutive "p" characters
103103
// start-find-evaluation
104104
$cursor = $collection->find(['name' => ['$regex' => 'p{2,}']]);
105105
foreach ($cursor as $doc) {
106-
echo json_encode($doc) . PHP_EOL;
106+
echo json_encode($doc) , PHP_EOL;
107107
}
108108
// end-find-evaluation

0 commit comments

Comments
 (0)