File: aggregation.md

package info (click to toggle)
mongo-java-driver 3.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, trixie
  • size: 16,112 kB
  • sloc: java: 102,506; xml: 395; sh: 43; makefile: 4
file content (105 lines) | stat: -rw-r--r-- 5,558 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
+++
date = "2016-08-01T11:35:05-04:00"
title = "Aggregation"
[menu.main]
  parent = "Async Tutorials"
  identifier = "Async Aggregation"
  weight = 20
  pre = "<i class='fa'></i>"

+++

## Aggregation Framework

The [aggregation pipeline]({{<docsref "core/aggregation-pipeline">}}) is a framework for data aggregation, modeled on the concept of data processing pipelines.

## Prerequisites

- The example below requires a ``restaurants`` collection in the ``test`` database. To create and populate the collection, follow the directions in [github] (https://github.com/mongodb/docs-assets/tree/drivers).

- Include the following import statements:

```java
import com.mongodb.Block;
import com.mongodb.async.client.*;
import com.mongodb.async.SingleResultCallback;

import com.mongodb.client.model.*;

import org.bson.Document;

import java.util.Arrays;
```

- Include the following callback code which the examples in the tutorials will use:

```java
SingleResultCallback<Void> callbackWhenFinished = new SingleResultCallback<Void>() {
    @Override
    public void onResult(final Void result, final Throwable t) {
        System.out.println("Operation Finished!");
    }
};
```

- Include the following code which the examples in the tutorials will use to print the results of the aggregation:

```java
Block<Document> printBlock = new Block<Document>() {
    @Override
    public void apply(final Document document) {
        System.out.println(document.toJson());
    }
};
```

## Connect to a MongoDB Deployment

Connect to a MongoDB deployment and declare and define a `MongoDatabase` and a `MongoCollection` instances.

For example, include the following code to connect to a standalone MongoDB deployment running on localhost on port `27017` and define `database` to refer to the `test` database and `collection` to refer to the `restaurants` collection:

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

For additional information on connecting to MongoDB, see [Connect to MongoDB]({{< relref "driver-async/tutorials/connect-to-mongodb.md" >}}).


## Perform Aggregation

To perform aggregation, pass a list of [aggregation stages]({{< docsref "meta/aggregation-quick-reference" >}}) to the [`MongoCollection.aggregate()`]({{<apiref "com/mongodb/client/MongoCollection.html#aggregate-java.util.List-">}}) method.
The Java driver provides the [`Aggregates`]({{< apiref "com/mongodb/client/model/Aggregates.html" >}}) helper class that contains builders for aggregation stages.

In the following example, the aggregation pipeline

- First uses a [`$match`]({{< docsref "reference/operator/aggregation/match/" >}}) stage to filter for documents whose `categories` array field contains the element `Bakery`. The example uses [`Aggregates.match`]({{< relref "builders/aggregation.md#match" >}}) to build the `$match` stage.

- Then, uses  a [`$group`]({{< docsref "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`. The example uses [`Aggregates.group`]({{< relref "builders/aggregation.md#group" >}}) to build the `$group` stage and [`Accumulators.sum`]({{< apiref "com/mongodb/client/model/Accumulators#sum-java.lang.String-TExpression-" >}}) to build the [accumulator expression]({{< docsref "reference/operator/aggregation/group/#accumulator-operator" >}}).  For the [accumulator expressions]({{< docsref "reference/operator/aggregation-group/" >}}) for use within the [`$group`]({{< docsref "reference/operator/aggregation/group/" >}}) stage, the Java driver provides [`Accumulators`]({{< apiref "com/mongodb/client/model/Accumulators.html">}}) helper class.

```java
collection.aggregate(Arrays.asList(
                        Aggregates.match(Filters.eq("categories", "Bakery")),
                        Aggregates.group("$stars", Accumulators.sum("count", 1))))
          .forEach(printBlock, callbackWhenFinished);
```

### Use Aggregation Expressions

For [$group accumulator expressions]({{< docsref "reference/operator/aggregation-group/" >}}), the Java driver provides [`Accumulators`]({{< apiref "com/mongodb/client/model/Accumulators.html">}}) helper class. For other [aggregation expressions]({{< docsref "meta/aggregation-quick-reference/#aggregation-expressions" >}}), manually build the expression `Document`.

In the following example, the aggregation pipeline uses a [`$project`]({{< docsref "reference/operator/aggregation/project/" >}}) stage to return only the `name` field and the calculated field `firstCategory` whose value is the first element in the `categories` array. The example uses [`Aggregates.project`]({{< relref "builders/aggregation.md#project" >}}) and various
[`Projections`]({{<apiref "com/mongodb/client/model/Projections.html">}}) methods to build the `$project` stage.

```java
collection.aggregate(Arrays.asList(Aggregates.project(Projections.fields(
                                        Projections.excludeId(),
                                        Projections.include("name"),
                                        Projections.computed(
                                                "firstCategory",
                                                new Document("$arrayElemAt",
                                                    Arrays.asList("$categories", 0)))))))
          .forEach(printBlock, callbackWhenFinished);
```