> 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
-->

# $sort (aggregation stage)

## Definition

Sorts all input documents and returns them to the pipeline in sorted order.

## Compatibility

You can use `$sort` 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

`$sort` has the following form:

```javascript
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
```

`$sort` takes a document that specifies the fields to sort by and their sort order. `<sort order>` can have one of the following values:

| Value | Description |
| --- | --- |
| `1` | Sort ascending. |
| `-1` | Sort descending. |
| `{ $meta: "textScore" }` | Sort by the computed `textScore` metadata in descending order. For an example, see [Text Score Metadata Sort.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#std-label-sort-pipeline-metadata) |

When sorting on multiple fields, `$sort` evaluates sort order from left to right. Documents are first sorted by `<field1>`, then documents with the same `<field1>` value are sorted by `<field2>`.

## Behavior

### Performance

`$sort` 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.

### Limits

- You can sort on a maximum of 32 keys.

- Providing a sort pattern with duplicate fields causes an error.

### Sort Consistency

MongoDB does not store documents in a collection in a particular order. When sorting on a field which contains duplicate values, documents containing those values may be returned in any order.

The `$sort` operation is not a "stable sort," which means that documents with equivalent sort keys are not guaranteed to remain in the same relative order in the output as they were in the input.

If the field specified in the sort criteria does not exist in two documents, then the value on which they are sorted is the same. The two documents may be returned in any order.

If consistent sort order is desired, include at least one field in your sort that contains unique values. The easiest way to guarantee this is to include the `_id` field in your sort query.

Consider the `movies` collection in the `sample_mflix` sample dataset. The following command sorts movies released in 1925 or 1926 by `year` in ascending order:

```javascript
db.movies.aggregate( [
   { $match: { year: { $in: [ 1925, 1926 ] } } },
   { $sort: { year: 1 } },
   { $project: { _id: 0, title: 1, year: 1 } }
] )

```

Because the `year` field has duplicate values for `1925` and `1926`, documents with the same value may sort differently across executions. For example, two runs of the previous command produce different orderings:

```javascript
[
   { title: "Clash of the Wolves", year: 1925 },
   { title: "Lady Windermere's Fan", year: 1925 },
   { title: "Grass: A Nation's Battle for Life", year: 1925 },
   { title: "Beau Geste", year: 1926 },
   { title: "The Black Pirate", year: 1926 },
   { title: "Ella Cinders", year: 1926 },
   { title: "For Heaven's Sake", year: 1926 },
   { title: "The Son of the Sheik", year: 1926 },
   { title: "The Strong Man", year: 1926 }
]

```

```javascript
[
   { title: "Lady Windermere's Fan", year: 1925 },
   { title: "Grass: A Nation's Battle for Life", year: 1925 },
   { title: "Clash of the Wolves", year: 1925 },
   { title: "The Strong Man", year: 1926 },
   { title: "The Black Pirate", year: 1926 },
   { title: "Ella Cinders", year: 1926 },
   { title: "Beau Geste", year: 1926 },
   { title: "The Son of the Sheik", year: 1926 },
   { title: "For Heaven's Sake", year: 1926 }
]
```

An operation sorts values for `year` in ascending order, but the order of the documents containing duplicate values for `year` is not the same. For example, duplicate values for `1925` and `1926`.

To achieve a *consistent sort*, add a field that contains only unique values to the sort. The following command sorts on both the `year` field and the `_id` field:

```javascript
db.movies.aggregate( [
   { $match: { year: { $in: [ 1925, 1926 ] } } },
   { $sort: { year: 1, _id: 1 } }
] )

```

The `_id` field always contains unique values and the sort order is consistent for multiple sort executions.

### Sort by an Array Field

When MongoDB sorts documents by an array-value field, the [sort key](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-sort-key) depends on whether the sort is ascending or descending:

- In an ascending sort, the sort key is the lowest value in the array.

- In a descending sort, the sort key is the highest value in the array.

The query filter does not affect sort key selection.

For example, consider these documents from the `movies` collection in the `sample_mflix` sample dataset:

```javascript
{
  _id: ObjectId("573a1395f29313caabce166c"),
  title: "The Comancheros",
  genres: [ "Action", "Western", "Adventure" ]
}
{
  _id: ObjectId("573a1391f29313caabcd8521"),
  title: "The Son of the Sheik",
  genres: [ "Adventure", "Drama" ]
}
```

The following queries sort the documents by the `genres` field in ascending and descending order:

```javascript
// Ascending sort
db.movies.aggregate( [
   {
      $match: {
         title: { $in: [
            "The Comancheros", "The Son of the Sheik"
         ] }
      }
   },
   {
      $sort: { genres: 1 }
   }
] )

```

```javascript
// Descending sort
db.movies.aggregate( [
   {
      $match: {
         title: { $in: [
            "The Comancheros", "The Son of the Sheik"
         ] }
      }
   },
   {
      $sort: { genres: -1 }
   }
] )

```

Both of the preceding queries return `The Comancheros` first because `Action` and `Western` are the lowest and highest entries in its `genres` array, respectively.

### Filter and Sort by an Array Field

When you filter and sort by a field that contains an array, the filter does not affect the value used as the [sort key](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-sort-key). The sort always considers all array values as potential sort keys.

For example, the following query finds movies whose `genres` array includes `"Drama"` or `"Western"` and sorts the results by `genres` in ascending order:

```javascript
db.movies.aggregate( [
   {
      $match: {
         title: { $in: [
            "The Comancheros", "The Son of the Sheik"
         ] },
         genres: { $in: [ "Drama", "Western" ] }
      }
   },
   {
      $sort: { genres: 1 }
   }
] )

```

The sort is ascending. The sort key is the first value in the `genres` array when sorted alphabetically:

- In `The Comancheros`, the first `genres` element is `Action`. This value is used as the sort key even though it does not match the filter `{ genres: { $in: [ "Drama", "Western" ] } }`.

- In `The Son of the Sheik`, the first `genres` element is `Adventure`. Similarly, this operation uses `Adventure`  as the sort key even though it does not match the filter.

The query returns `The Comancheros` first.

**Tip: Sort only by Matched Values**

To only consider matched values as potential sort keys, you can generate a new field containing the matched values and sort on that field. For more information, see these pipeline stages and expressions:

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

- [`$filter`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter.md#mongodb-expression-exp.-filter)

### $sort Operator and Memory

### $sort and $limit Memory Optimization

When a [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort) precedes a [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) and there are no intervening stages that modify the number of documents, the optimizer can coalesce the [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) into the [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort). This allows the [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort) operation to only maintain the top `n` results as it progresses, where `n` is the specified limit, and ensures that MongoDB only needs to store `n` items in memory. This optimization still applies when `allowDiskUse` is `true` and the `n` items exceed the [aggregation memory limit.](https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md#std-label-agg-memory-restrictions)

Optimizations are subject to change between releases.

### $sort and Memory Restrictions

Pipeline stages that require more than 100 megabytes of memory to execute write temporary files to disk by default. These temporary files last for the duration of the pipeline execution and can influence storage space on your instance.

Individual `find` and `aggregate` commands can override the [`allowDiskUseByDefault`](https://www.mongodb.com/docs/manual/reference/parameters.md#mongodb-parameter-param.allowDiskUseByDefault) parameter by either:

- Using `{ allowDiskUse: true }` to allow writing temporary files out to disk when `allowDiskUseByDefault` is set to `false`

- Using `{ allowDiskUse: false }` to prohibit writing temporary files out to disk when `allowDiskUseByDefault` is set to `true`

**Note:**

For MongoDB Atlas, it is recommended to [configure storage auto-scaling](https://www.mongodb.com/docs/atlas/cluster-autoscaling.md#std-label-cluster-autoscaling) to prevent long-running queries from filling up storage with temporary files.

If your Atlas cluster uses storage auto-scaling, the temporary files may cause your cluster to scale to the next storage tier.

For additional details, see [Aggregation Pipeline Limits.](https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md#std-label-agg-pipeline-limits)

### $sort Index Use

The `$sort` operator can use an index when it is the first stage in a pipeline or is preceded only by a [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage.

When you use `$sort` on a sharded cluster, each shard sorts its result documents using an index where available. Then the [`mongos`](https://www.mongodb.com/docs/manual/reference/program/mongos.md#mongodb-binary-bin.mongos) or one of the shards performs a streamed merge sort.

## Examples

The examples on this page use data from the [sample\_mflix 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.

### MongoDB Shell

### Ascending and Descending Sort

For each sort field, set the value to `1` for ascending or `-1` for descending. For example:

```javascript
db.movies.aggregate(
   [
     { $sort: { year: -1, title: 1 } },
     { $limit: 5 }
   ]
)

```

This operation sorts documents in the `movies` collection descending by `year`, then ascending by `title`, and returns the first five results.

When comparing values of different [BSON types](https://www.mongodb.com/docs/manual/reference/bson-types.md#std-label-bson-types) in sort operations, MongoDB uses the following comparison order, from lowest to highest:

1. MinKey (internal type)

2. Null

3. Numbers (ints, longs, doubles, decimals)

4. Symbol, String

5. Object

6. Array

7. BinData

8. ObjectId

9. Boolean

10. Date

11. Timestamp

12. Regular Expression

13. JavaScript Code

14. JavaScript Code with Scope

15. MaxKey (internal type)

For details on the comparison/sort order for specific types, see [Comparison/Sort Order.](https://www.mongodb.com/docs/manual/reference/bson-type-comparison-order.md#std-label-bson-types-comparison-order)

### Text Score Metadata Sort

**Note:**

`$text` provides text query capabilities for self-managed (non-Atlas) deployments. For data hosted on MongoDB, MongoDB also offers an improved full-text query solution, [MongoDB Search.](https://www.mongodb.com/docs/atlas/atlas-search/)

The following example uses the `movies` collection in the `sample_mflix` sample dataset. Before running it, create a text index on the `plot` field:

```javascript
db.movies.createIndex( { plot: "text" } )

```

For a pipeline that includes [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text), you can sort by descending relevance score using the [`{ $meta: "textScore" }`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta.md#mongodb-expression-exp.-meta) expression. In the `{ <sort-key> }` document, set the [`{ $meta: "textScore" }`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta.md#mongodb-expression-exp.-meta) expression to an arbitrary field name. The field name is ignored by the query system. For example:

```javascript
db.movies.aggregate(
   [
     { $match: { $text: { $search: "pirate" } } },
     { $sort: { score: { $meta: "textScore" }, year: -1 } },
     { $limit: 5 }
   ]
)

```

This operation matches documents with `$text`, then sorts descending by `"textScore"` metadata and by `year`, and returns the first five results. The `score` field name in the sort document is ignored by the query system. The projection doesn't include the `"textScore"` metadata and does not return the metadata as part of the matching documents. See [`$meta`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta.md#mongodb-expression-exp.-meta) for more information.

## Learn More

For full aggregation examples that use `$sort`, see [Complete Aggregation Pipeline Tutorials.](https://www.mongodb.com/docs/manual/tutorial/aggregation-complete-examples.md#std-label-aggregation-complete-examples)
