> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  drivers: shell, csharp, nodejs
-->

# $group (aggregation stage)

## Definition

The $group stage combines multiple documents with the same field, fields, or expression into a single document according to a group key. The result is one document per unique group key.

A group key is often a field, or group of fields. The group key can also be the result of an expression. Use the `_id` field in the `$group` pipeline stage to set the group key. See below for [usage examples.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#std-label-ex-agg-group-stage)

In the `$group` stage output, the `_id` field is set to the group key for that document.

The output documents can also contain additional fields that are set using [accumulator expressions.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#std-label-accumulators-group)

**Note:**

[`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) does *not* order its output documents.

## Compatibility

You can use `$group` for deployments hosted in the following environments:

- [MongoDB Atlas](https://www.mongodb.com/docs/atlas): The fully managed service for MongoDB deployments in the cloud

* [MongoDB Enterprise](https://www.mongodb.com/docs/manual/administration/install-enterprise.md#std-label-install-mdb-enterprise): The subscription-based, self-managed version of MongoDB

* [MongoDB Community](https://www.mongodb.com/docs/manual/administration/install-community.md#std-label-install-mdb-community-edition): The source-available, free-to-use, and self-managed version of MongoDB

## Syntax

The [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage has the following prototype form:

```javascript
{
 $group:
   {
     _id: <expression>, // Group key
     <field1>: { <accumulator1> : <expression1> },
     ...
   }
 }
```

| Field | Description |
| --- | --- |
| `_id` | *Required.* The `_id` expression specifies the group key. If you specify an `_id` value of null, or any other constant value, the `$group` stage returns a single document that aggregates values across all of the input documents. [See the Group by Null example.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#std-label-null-example) |
| `field` | *Optional.* Computed using the [accumulator operators.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#std-label-accumulators-group) |

The `_id` and the [accumulator operators](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#std-label-accumulators-group) can accept any valid `expression`. For more information on expressions, see [Expressions.](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions)

## Considerations

### Performance

`$group` is a blocking stage, which causes the pipeline to wait for all input data to be retrieved for the blocking stage before processing the data. A blocking stage may reduce performance because it reduces parallel processing for a pipeline with multiple stages. A blocking stage may also use substantial amounts of memory for large data sets.

### Accumulator Operator

The `<accumulator>` operator must be one of the following accumulator operators:

| Name | Description |
| --- | --- |
| [`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator) | Returns the result of a user-defined accumulator function. |
| [`$addToSet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addToSet.md#mongodb-group-grp.-addToSet) | Returns an array of *unique* expression values for each group. Order of the array elements is undefined. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$avg`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg.md#mongodb-group-grp.-avg) | Returns an average of numerical values. Ignores non-numeric values. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$bottom`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom.md#mongodb-group-grp.-bottom) | Returns the bottom element within a group according to the specified sort order. **New in version 5.2** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |
| [`$bottomN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN.md#mongodb-group-grp.-bottomN) | Returns an aggregation of the bottom `n` fields within a group, according to the specified sort order. **New in version 5.2** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |
| [`$concatArrays`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays.md#mongodb-group-grp.-concatArrays) | Returns a single array that combines the elements of two or more arrays. **New in version 8.1** |
| [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator.md#mongodb-group-grp.-count) | Returns the number of documents in a group. Distinct from the [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count) pipeline stage. **New in version 5.0** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |
| [`$first`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/first.md#mongodb-group-grp.-first) | Returns the result of an [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) for the first document in a group. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$firstN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN.md#mongodb-group-grp.-firstN) | Returns an aggregation of the first `n` elements within a group. Only meaningful when documents are in a defined order. Distinct from the [`$firstN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN.md#mongodb-expression-exp.-firstN) array operator. **New in version 5.2** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |
| [`$last`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/last.md#mongodb-group-grp.-last) | Returns the result of an [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) for the last document in a group. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$lastN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN.md#mongodb-group-grp.-lastN) | Returns an aggregation of the last `n` elements within a group. Only meaningful when documents are in a defined order. Distinct from the [`$lastN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN.md#mongodb-expression-exp.-lastN) array operator. **New in version 5.2** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |
| [`$max`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/max.md#mongodb-group-grp.-max) | Returns the highest expression value for each group. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$maxN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN.md#mongodb-group-grp.-maxN) | Returns an aggregation of the `n` maximum valued elements in a group. Distinct from the [`$maxN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN-array-element.md#mongodb-expression-exp.-maxN) array operator. **New in version 5.2** Available in [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) and as an [expression.](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) |
| [`$median`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/median.md#mongodb-group-grp.-median) | Returns an approximation of the [median](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-median), the 50th [percentile](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-percentile), as a scalar value. **New in version 7.0** This operator is available as an accumulator in these stages: [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group); [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) It is also available as an [aggregation expression.](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) |
| [`$mergeObjects`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects.md#mongodb-expression-exp.-mergeObjects) | Returns a document created by combining the input documents for each group. |
| [`$min`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/min.md#mongodb-group-grp.-min) | Returns the lowest expression value for each group. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$minN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN.md#mongodb-group-grp.-minN) | Returns an aggregation of the `n` minimum valued elements in a group. Distinct from the [`$minN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN-array-element.md#mongodb-expression-exp.-minN) array operator. **New in version 5.2** Available in [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) and as an [expression.](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) |
| [`$percentile`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile.md#mongodb-group-grp.-percentile) | Returns an array of scalar values that correspond to specified [percentile](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-percentile) values. **New in version 7.0** This operator is available as an accumulator in these stages: [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group); [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) It is also available as an [aggregation expression.](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) |
| [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push) | Returns an array of expression values for documents in each group. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$setUnion`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion.md#mongodb-group-grp.-setUnion) | Takes two or more arrays and returns an array containing the elements that appear in any input array. **New in version 8.1** |
| [`$stdDevPop`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop.md#mongodb-group-grp.-stdDevPop) | Returns the population standard deviation of the input values. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$stdDevSamp`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp.md#mongodb-group-grp.-stdDevSamp) | Returns the sample standard deviation of the input values. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) | Returns a sum of numerical values. Ignores non-numeric values. **Changed in version 5.0** Available in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stage. |
| [`$top`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/top.md#mongodb-group-grp.-top) | Returns the top element within a group according to the specified sort order. **New in version 5.2** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |
| [`$topN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN.md#mongodb-group-grp.-topN) | Returns an aggregation of the top `n` fields within a group, according to the specified sort order. **New in version 5.2** Available in the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) and [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md#mongodb-pipeline-pipe.-setWindowFields) stages. |

### `$group` and Memory Restrictions

If the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage exceeds 100 megabytes of RAM, MongoDB writes data to temporary files. However, if the [allowDiskUse](https://www.mongodb.com/docs/manual/reference/command/aggregate.md#std-label-aggregate-cmd-allowDiskUse) option is set to `false`, `$group` returns an error. For more information, refer to [aggregation pipeline limits.](https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md#std-label-agg-pipeline-limits)

### `$group` Performance Optimizations

This section describes optimizations to improve the performance of [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group). There are optimizations that you can make manually and optimizations MongoDB makes internally.

#### Optimization to Return the First or Last Document of Each Group

If a pipeline [`sorts`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort) and [`groups`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) by the same field and the `$group` stage only uses the [`$first`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/first.md#mongodb-group-grp.-first) or [`$last`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/last.md#mongodb-group-grp.-last) accumulator operator, consider adding an [index](https://www.mongodb.com/docs/manual/indexes.md#std-label-indexes) on the grouped field which matches the sort order. In some cases, the `$group` stage can use the index to quickly find the first or last document of each group.

**Example:**

If the `movies` collection contains an index `{ year: 1, title: 1 }`, the following pipeline can use that index to find the first document of each group:

```javascript
db.movies.aggregate([
   {
      $sort: { year: 1, title: 1 }
   },
   {
      $group: {
         _id: { year: "$year" },
         title: { $first: "$title" }
      }
   }
])

```

#### Slot-Based Query Execution Engine

Starting in version 5.2, MongoDB uses the [slot-based execution query engine](https://www.mongodb.com/docs/manual/reference/sbe.md#std-label-sbe-landing) to execute [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stages if either:

- `$group` is the first stage in the pipeline.

- All preceding stages in the pipeline can also be executed by the slot-based execution engine.

For more information, see [`$group` Optimization.](https://www.mongodb.com/docs/manual/core/aggregation-pipeline-optimization.md#std-label-agg-group-optimization-sbe)

## Examples

### MongoDB Shell

### Count the Number of Documents in a Collection

The examples on this page use data from the [sample\_mflix sample dataset](https://www.mongodb.com/docs/manual/sample-data/sample-mflix.md#std-label-sample-mflix). For details on how to load this dataset into your self-managed MongoDB deployment, see [Load the sample dataset](https://www.mongodb.com/docs/manual/sample-data/load-sample-data-local.md#std-label-sample-dataset-local). If you made any modifications to the sample databases, you may need to drop and recreate the databases to run the examples on this page.

The following aggregation operation uses the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage to count the number of documents in the `movies` collection:

```javascript
db.movies.aggregate([
   {
      $group: {
         _id: null,
         count: { $count: {} }
      }
   }
])

```

**Output:**

```javascript
[
  {
    _id: null,
    count: 21349
  }
]

```

This aggregation operation is equivalent to the following SQL statement:

```sql
SELECT COUNT(*) AS count FROM movies
```

**See also:**

- [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count)

- [`$count (aggregation accumulator)`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator.md#mongodb-group-grp.-count)

### Retrieve Distinct Values

The following aggregation operation uses the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage to retrieve the distinct `rated` values from the `movies` collection:

```javascript
db.movies.aggregate( [ { $group : { _id : "$rated" } } ] )

```

**Output:**

```javascript
[
  {
    _id: 'TV-PG'
  },
  {
    _id: 'PG'
  },
  {
    _id: 'TV-14'
  },
  {
    _id: 'OPEN'
  },
  {
    _id: 'Not Rated'
  },
  {
    _id: 'GP'
  },
  {
    _id: 'TV-Y7'
  },
  {
    _id: 'G'
  },
  {
    _id: 'PG-13'
  },
  {
    _id: null
  },
  {
    _id: 'M'
  },
  {
    _id: 'R'
  },
  {
    _id: 'TV-MA'
  },
  {
    _id: 'APPROVED'
  },
  {
    _id: 'PASSED'
  },
  {
    _id: 'Approved'
  },
  {
    _id: 'AO'
  },
  {
    _id: 'TV-G'
  }
]

```

**Note:**

For example, `$group` operations of the following form can result in a `DISTINCT_SCAN`:

```javascript
{ $group : { _id : "$<field>" } }
```

For more information on behavior for retrieving distinct values, see the [distinct command behavior.](https://www.mongodb.com/docs/manual/reference/command/distinct.md#std-label-distinct-command-behavior)

To see whether your operation results in a `DISTINCT_SCAN`, check your operation's [explain results.](https://www.mongodb.com/docs/manual/reference/explain-results.md#std-label-explain-results)

### Group by Rating

The following aggregation operation groups documents by the `rated` field, calculating the total runtime per rating and returning only the ratings with a total runtime greater than or equal to 100000:

```javascript
db.movies.aggregate(
   [
      // First Stage
      {
         $group: {
            _id: "$rated",
            totalRuntime: { $sum: "$runtime" }
         }
      },
      // Second Stage
      {
         $match: { "totalRuntime": { $gte: 100000 } }
      }
   ]
)

```

**Output:**

```javascript
[
  {
    _id: 'PG-13',
    totalRuntime: 250843
  },
  {
    _id: 'R',
    totalRuntime: 582318
  },
  {
    _id: null,
    totalRuntime: 967127
  },
  {
    _id: 'PG',
    totalRuntime: 191204
  }
]

```

First Stage:

The [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage groups the documents by `rated` to retrieve the distinct rating values. This stage returns the `totalRuntime` for each rating group.

Second Stage:

The [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage filters the resulting documents to return only ratings with a `totalRuntime` greater than or equal to 100000.

This aggregation operation is equivalent to the following SQL statement:

```sql
SELECT rated,
   Sum(runtime) AS totalRuntime
FROM   movies
GROUP  BY rated
HAVING totalRuntime >= 100000
```

**See also:**

[`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match)

### Calculate Count, Sum, and Average

#### Group by Year

The following pipeline calculates the total runtime, average runtime, and movie count for each year before 1910:

```javascript
db.movies.aggregate([
   { $match: { "year": { $lt: 1910 } } },
   {
      $group: {
         _id: "$year",
         totalRuntime: { $sum: "$runtime" },
         averageRuntime: { $avg: "$runtime" },
         count: { $sum: 1 }
      }
   },
   { $sort: { totalRuntime: -1 } }
])

```

**Output:**

```javascript
[
  { _id: 1909, totalRuntime: 14, averageRuntime: 14, count: 1 },
  { _id: 1903, totalRuntime: 11, averageRuntime: 11, count: 1 },
  { _id: 1896, totalRuntime: 2, averageRuntime: 1, count: 2 }
]

```

First Stage:

The [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage filters the documents to only pass movies released before 1910 to the next stage.

Second Stage:

The [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) stage groups the documents by year and calculates the total runtime, average runtime, and total count of the documents in each group.

Third Stage:

The [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort) stage sorts the results by the total runtime for each group in descending order.

This aggregation operation is equivalent to the following SQL statement:

```sql
SELECT year,
       Sum(runtime) AS totalRuntime,
       Avg(runtime) AS averageRuntime,
       Count(*)     AS count
FROM   movies
WHERE  year < 1910
GROUP  BY year
ORDER  BY totalRuntime DESC
```

**See also:**

- [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match)

- [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort)

- [`db.collection.countDocuments()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.countDocuments.md#mongodb-method-db.collection.countDocuments) which wraps the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) aggregation stage with a [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) expression.

#### Group by `null`

The following aggregation operation specifies a group `_id` of `null`, calculating the total runtime, average runtime, and count of all documents in the collection.

```javascript
db.movies.aggregate([
   {
      $group: {
         _id: null,
         totalRuntime: { $sum: "$runtime" },
         averageRuntime: { $avg: "$runtime" },
         count: { $sum: 1 }
      }
   }
])

```

**Output:**

```javascript
[
  {
    _id: null,
    totalRuntime: 2167458,
    averageRuntime: 103.65652797704448,
    count: 21349
  }
]

```

This aggregation operation is equivalent to the following SQL statement:

```sql
SELECT Sum(runtime) AS totalRuntime,
       Avg(runtime) AS averageRuntime,
       Count(*)     AS count
FROM   movies
```

**See also:**

- [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count)

- [`db.collection.countDocuments()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.countDocuments.md#mongodb-method-db.collection.countDocuments) which wraps the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) aggregation stage with a [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) expression.

### Pivot Data

#### Group Titles by Year

The following aggregation operation pivots the data in the `movies` collection to group titles by year:

```javascript
db.movies.aggregate([
   { $match: { year: { $lt: 1910 } } },
   { $group: { _id: "$year", titles: { $push: "$title" } } },
   { $sort: { _id: 1 } }
])

```

**Output:**

```javascript
[
  { _id: 1896, titles: [ 'The Kiss', 'The Kiss' ] },
  { _id: 1903, titles: [ 'The Great Train Robbery' ] },
  { _id: 1909, titles: [ 'A Corner in Wheat' ] }
]

```

#### Group Documents by Year

The following aggregation operation groups documents by year:

```javascript
db.movies.aggregate([
   { $match: { year: { $lt: 1910 } } },
   { $group: { _id: "$year", movies: { $push: "$$ROOT" } } },
   {
      $addFields: {
         totalRuntime: { $sum: "$movies.runtime" }
      }
   },
   { $sort: { _id: 1 } }
])

```

**Output:**

```javascript
[
  { _id: 1896, movies: '...', totalRuntime: 2 },
  { _id: 1903, movies: '...', totalRuntime: 11 },
  { _id: 1909, movies: '...', totalRuntime: 14 }
]

```

First Stage:

[`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) filters the documents to only pass movies released before 1910 to the next stage.

Second Stage:

[`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) uses the [`$$ROOT`](https://www.mongodb.com/docs/manual/reference/aggregation-variables.md#mongodb-variable-variable.ROOT) system variable to group the entire documents by year.

Third Stage:

[`$addFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields.md#mongodb-pipeline-pipe.-addFields) adds a field to the output containing the total runtime of movies for each year.

**Note:**

The resulting documents must not exceed the [BSON Document Size](https://www.mongodb.com/docs/manual/reference/limits.md#mongodb-limit-BSON-Document-Size) limit of 16 mebibytes.

Fourth Stage:

[`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort) sorts the resulting documents by `_id` in ascending order.

## Learn More

The [Group and Total Data](https://www.mongodb.com/docs/manual/tutorial/aggregation-examples/group-and-total.md#std-label-agg-example-group-data) tutorial provides an extensive example of the [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) operator in a common use case.

To learn more about related pipeline stages, see the [`$addFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields.md#mongodb-pipeline-pipe.-addFields) guide.
