Skip to content

DOCSP-33664: fix explain agg code + other fixes #503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions source/compatibility.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Compatibility
:depth: 2
:class: singlecol

Connect to a Compatible MongoDB Deployment
------------------------------------------

You can use the {+driver-short+} to connect to deployments hosted in the
following environments:
Expand Down
134 changes: 81 additions & 53 deletions source/fundamentals/aggregation.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
.. _java-aggregation:

===========
Aggregation
===========

.. facet::
:name: genre
:values: reference

.. meta::
:keywords: code example, transform, computed

.. contents:: On this page
:local:
:backlinks: none
Expand All @@ -11,39 +20,41 @@ Aggregation
Overview
--------

.. _java-aggregation:

In this guide, you can learn how to use **aggregation operations** in the MongoDB Java driver.
In this guide, you can learn how to use the {+driver-short+} to perform
**aggregation operations**.

Aggregation operations process data in your MongoDB collections and
return computed results. The MongoDB Aggregation framework, part of the
Query API, is modeled on the concept of data processing pipelines.
Documents enter a pipeline comprised of one or more stages that
transforms the documents into an aggregated result.
return computed results. The MongoDB Aggregation framework, which is
part of the Query API, is modeled on the concept of data processing
pipelines. Documents enter a pipeline comprised of one or more stages,
and this pipeline transforms the documents into an aggregated result.

Another way to think of aggregation is like a car factory. Within the car factory is an assembly line, along which
are assembly stations with specialized tools to do a specific job, like drills and welders. Raw parts enter the factory,
which are then transformed and assembled into a finished product.
An aggregation operation is similar to a car factory. A car factory has
an assembly line, which contains assembly stations with specialized
tools to do specific jobs, like drills and welders. Raw parts enter the
factory, and then the assembly line transforms and assembles them into a
finished product.

The **aggregation pipeline** is the assembly line, **aggregation stages** are the assembly stations, and
**operator expressions** are the specialized tools.
The **aggregation pipeline** is the assembly line, **aggregation
stages** are the assembly stations, and **operator expressions** are the
specialized tools.

Aggregation and Find Operations Compared
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compare Aggregation and Find Operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Using ``find`` operations, you can:
You can use find operations to perform the following actions:

- select *what* documents to return
- select *what* fields to return
- sort the results
- Select *what* documents to return
- Select *what* fields to return
- Sort the results

Using ``aggregation`` operations, you can:
You can use aggregation operations to perform the following actions:

- perform all ``find`` operations
- rename fields
- calculate fields
- summarize data
- group values
- Perform find operations
- Rename fields
- Calculate fields
- Summarize data
- Group values

Aggregation operations have some :manual:`limitations </core/aggregation-pipeline-limits/>` you must keep in mind:

Expand All @@ -70,8 +81,8 @@ Useful References
Runnable Examples
-----------------

Base Setup
~~~~~~~~~~
Import Classes
~~~~~~~~~~~~~~

Create a new Java file called ``AggTour.java`` and include the following import statements:

Expand All @@ -81,7 +92,6 @@ Create a new Java file called ``AggTour.java`` and include the following import
:start-after: begin imports
:end-before: end imports


Connect to a MongoDB Deployment
+++++++++++++++++++++++++++++++

Expand All @@ -91,22 +101,23 @@ Connect to a MongoDB Deployment

public static void main(String[] args) {
// Replace the uri string with your MongoDB deployment's connection string
String uri = "<connection string uri>";
String uri = "<connection string>";

MongoClient mongoClient = MongoClients.create(uri);
MongoDatabase database = mongoClient.getDatabase("aggregation");
MongoCollection<Document> collection = database.getCollection("restaurants");

// aggregation here
// Paste the aggregation code here
}
}

.. seealso::
.. tip::

For information on connecting to MongoDB, see the :ref:`Connection Guide <mongoclient>`
To learn more about connecting to MongoDB, see the :ref:`Connection
Guide <connect-to-mongodb>`.

Insert the Data
+++++++++++++++
Insert Sample Data
++++++++++++++++++

.. literalinclude:: /includes/fundamentals/code-snippets/AggTour.java
:language: java
Expand All @@ -133,15 +144,15 @@ In the following example, the aggregation pipeline:
- Uses a :manual:`$group </reference/operator/aggregation/group/>` stage to group the matching documents by the ``stars``
field, accumulating a count of documents for each distinct value of ``stars``.

.. seealso::
.. note::

You can build the expressions used in this example using the :ref:`aggregation builders <aggregates-builders>`.

.. literalinclude:: /includes/fundamentals/code-snippets/AggTour.java
:language: java
:dedent:
:start-after: begin aggregation one
:end-before: end aggregation one
:start-after: begin aggregation basic
:end-before: end aggregation basic

The preceding aggregation should produce the following results:

Expand All @@ -164,32 +175,45 @@ To view information about how MongoDB executes your operation, use the
``explain()`` method of the ``AggregateIterable`` class. The ``explain()``
method returns **execution plans** and performance statistics. An execution
plan is a potential way MongoDB can complete an operation.
The ``explain()`` method provides both the winning plan (the plan MongoDB
executed) and rejected plans.
The ``explain()`` method provides both the winning plan, which is the plan MongoDB
executed, and any rejected plans.

.. tip::

To learn more about query plans and execution statistics, see
:manual:`Explain Results </reference/explain-results/>` in the Server manual.

.. include:: /includes/fundamentals/explain-verbosity.rst

In the following example, we print the JSON representation of the
winning plans for aggregation stages that produce execution plans:
The following example prints the JSON representation of the
winning plans for any aggregation stages that produce execution plans:

.. literalinclude:: /includes/fundamentals/code-snippets/AggTour.java
:language: java
:dedent:
:start-after: begin aggregation three
:end-before: end aggregation three
:start-after: begin aggregation explain
:end-before: end aggregation explain

The preceding code snippet should produce the following output:
The example produces the following output as the ``$group`` stage
is the only stage that produces an execution plan:

.. code-block:: none
:copyable: false

{ "stage": "PROJECTION_SIMPLE",
"transformBy": {"stars": 1, "_id": 0},
{
"stage": "GROUP",
"planNodeId": 2,
"inputStage": {
"stage": "COLLSCAN",
"filter": {
"categories": {"$eq":"bakery"}},
"direction": "forward"}}
"stage": "COLLSCAN",
"planNodeId": 1,
"filter": {
"categories": {
"$eq": "Bakery"
}
},
"direction": "forward"
}
}

For more information about the topics mentioned in this section, see the
following resources:
Expand All @@ -203,7 +227,7 @@ following resources:
Aggregation Expression Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The Java driver provides builders for accumulator expressions for use with
The {+driver-short+} provides builders for accumulator expressions for use with
``$group``. You must declare all other expressions in JSON format or
compatible document format.

Expand All @@ -213,7 +237,7 @@ compatible document format.
expression.

The ``$`` in front of "categories" tells MongoDB that this is a :manual:`field path </meta/aggregation-quick-reference/#expressions>`,
using the "categories" field from the input document.
using the ``categories`` field from the input document.

.. code-block:: java
:copyable: false
Expand All @@ -225,6 +249,10 @@ compatible document format.

Document.parse("{ $arrayElemAt: ['$categories', 0] }")

Alternatively, you can construct expressions by using the Aggregation
Expression Operations API. To learn more, see
:ref:`java-aggregation-expression-operations`.

In the following example, the aggregation pipeline uses a
``$project`` stage and various ``Projections`` to return the ``name``
field and the calculated field ``firstCategory`` whose value is the
Expand All @@ -233,8 +261,8 @@ first element in the ``categories`` field.
.. literalinclude:: /includes/fundamentals/code-snippets/AggTour.java
:language: java
:dedent:
:start-after: begin aggregation two
:end-before: end aggregation two
:start-after: begin aggregation expression
:end-before: end aggregation expression

The preceding aggregation should produce the following results:

Expand Down
8 changes: 4 additions & 4 deletions source/includes/fact-environments.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
- `MongoDB Atlas
<https://www.mongodb.com/docs/atlas>`__: The fully
<https://www.mongodb.com/docs/atlas>`__: the fully
managed service for MongoDB deployments in the cloud
- :ref:`MongoDB Enterprise <install-mdb-enterprise>`: The
- :ref:`MongoDB Enterprise <install-mdb-enterprise>`: the
subscription-based, self-managed version of MongoDB
- :ref:`MongoDB Community <install-mdb-community-edition>`: The
source-available, free-to-use, and self-managed version of MongoDB
- :ref:`MongoDB Community <install-mdb-community-edition>`: the
source-available, free-to-use, and self-managed version of MongoDB
47 changes: 24 additions & 23 deletions source/includes/fundamentals/code-snippets/AggTour.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package docs.aggregation;

// begin imports

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
Expand All @@ -12,18 +11,18 @@
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import org.bson.Document;
import org.bson.json.JsonWriterSettings;

import java.util.Arrays;
import java.util.List;

// end imports

// begin class intro
// begin connection
public class AggTour {
public static void main(String[] args) {
// Replace the uri string with your MongoDB deployment's connection string
final String uri = "<connection string uri>";
final String uri = "<connection string>";

MongoClient mongoClient = MongoClients.create(uri);
MongoDatabase database = mongoClient.getDatabase("aggregation");
Expand All @@ -49,37 +48,36 @@ public static void main(String[] args) {
// end insert

// Creates an aggregation pipeline that matches documents, groups them by the "stars" field, and tallies them by distinct values
// begin aggregation one
// begin aggregation basic
collection.aggregate(
Arrays.asList(
Aggregates.match(Filters.eq("categories", "Bakery")),
Aggregates.group("$stars", Accumulators.sum("count", 1))
)
// Prints the result of the aggregation operation as JSON
).forEach(doc -> System.out.println(doc.toJson()));
// end aggregation one
// end aggregation basic

// begin aggregation three
// begin aggregation explain
Document explanation = collection.aggregate(
Arrays.asList(
Aggregates.match(Filters.eq("categories", "Bakery")),
Aggregates.group("$stars", Accumulators.sum("count", 1))
)
Arrays.asList(
Aggregates.match(Filters.eq("categories", "Bakery")),
Aggregates.group("$stars", Accumulators.sum("count", 1))
)
).explain(ExplainVerbosity.EXECUTION_STATS);

List<Document> stages = explanation.get("stages", List.class);
List<String> keys = Arrays.asList("queryPlanner", "winningPlan");
String winningPlans = explanation
.getEmbedded(
Arrays.asList("queryPlanner", "winningPlan", "queryPlan"),
Document.class
)
.toJson(JsonWriterSettings.builder().indent(true).build());

System.out.println(winningPlans);
// end aggregation explain

// Prints the JSON representation of the winning execution plans
for (Document stage : stages) {
Document cursorStage = stage.get("$cursor", Document.class);
if (cursorStage != null) {
System.out.println(cursorStage.getEmbedded(keys, Document.class).toJson());
}
}
// end aggregation three
// Prints the restaurant name and the first value in the "categories" array as a field named "firstCategory"
// begin aggregation two
// begin aggregation expression
collection.aggregate(
Arrays.asList(
Aggregates.project(
Expand All @@ -88,12 +86,15 @@ public static void main(String[] args) {
Projections.include("name"),
Projections.computed(
"firstCategory",
new Document("$arrayElemAt", Arrays.asList("$categories", 0))
new Document(
"$arrayElemAt",
Arrays.asList("$categories", 0)
)
)
)
)
)
).forEach(doc -> System.out.println(doc.toJson()));
// end aggregation two
// end aggregation expression
}
}
8 changes: 4 additions & 4 deletions source/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ If your Java application requires asynchronous stream processing, use the
:driver:`Reactive Streams Driver </reactive-streams/>` which uses Reactive
Streams to make non-blocking calls to MongoDB.

Compatibility
-------------
Connect to a Compatible MongoDB Deployment
------------------------------------------

You can use the {+driver-short+} to connect to deployments hosted in the
following environments:
You can use the {+driver-short+} to connect to MongoDB
deployments running on one of the following hosted services or editions:

.. include:: /includes/fact-environments.rst

Expand Down