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

# Paginate the Results

On clusters running MongoDB 7.0.5+, use MongoDB Search to retrieve your [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query results sequentially after or before a reference point. Use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` or `searchBefore` options to traverse results in-order and build "Next Page" and "Previous Page" functions in your application.

## Usage

To retrieve paginated results, perform the following steps:

[Create an index](https://www.mongodb.com/docs/search/indexes/manage-indexes.md#std-label-ref-create-index) on the fields you want to query.

Run a [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query that returns a point of reference. To learn more, see [Retrieve Point of Reference.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-paginate-results-search-sequence-token)

Use the point of reference in your subsequent [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query to retrieve the next or previous set of documents in the results.

- To learn more about retrieving results to build a "Next Page" function, see [Search After a Specific Point of Reference.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-paginate-results-search-after)

- To learn more about retrieving results to build a "Previous Page" function, see [Search Before a Specific Point of Reference.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-paginate-results-search-before)

- To jump to a page in your results, combine [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) and [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` or `searchBefore` options. For example, to jump to results from Page 3 to Page 5, with 10 results per page, do the following:

  Retrieve results using `searchAfter` with the point of reference for the last result on Page 3 (Result 30).

  Use [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) to skip the 10 results on Page 4 (Results 31-40) and [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) to limit the results to 10 documents.

  Return results for Page 5 (Results 41-50).

  Here, using [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) with the `searchAfter` option optimizes the query to skip only 1 page of results (10 documents). By comparison, if you use `$skip` without the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` option, the query skips 4 pages of results (40 documents). To learn more, see [Jump from Page 2 to Page 5 Using searchAfter and $skip.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-skip-query)

## Considerations

- A tie occurs when you sort on a field for which multiple documents have identical values. MongoDB doesn't guarantee ordering of tied query results, which can lead to duplication and inconsistency when you use `searchAfter` and `searchBefore`. Apply the following principles to reduce relevance score ties:

  - Sort your query by a unique field to prevent relevance score ties. For an example, see [Sort by Score And a Unique Field.](https://www.mongodb.com/docs/search/query/sort.md#std-label-fts-sort-score-unique-field)

  - If you want to primarily sort by a non-unique field, add a secondary sort clause on a unique field to serve as a tiebreaker.

- Updating or deleting documents between queries might cause inconsistencies in result order. Apply the following principles to support deterministic search behavior:

  - Sort your query results by an immutable field, such as `_id`. MongoDB Search reflects the updates you make to your collection between initial and subsequent queries. If you sort by a mutable field such as `updated_time` and you update your collection between your first and second queries, MongoDB Search might order the same documents differently.

  - If you deployed [dedicated Search nodes](https://www.mongodb.com/docs/search/deployment/deployment-options.md#std-label-node-architecture) and you are sorting results by `searchScore`, consider the following:
    - By default, MongoDB Search scores documents using the `bm25` similarity algorithm, which calculates term frequency in relation to the entire corpus of documents on the MongoDB Search node. Because each MongoDB Search node replicates from the changestream independently, this corpus might vary across MongoDB Search nodes. As a result, the same query can return different `bm25` scores when routed to different MongoDB Search nodes. Subsequent queries are more likely to be routed to different MongoDB Search nodes if your deployment uses [dedicated MongoDB Search nodes](https://www.mongodb.com/docs/search/deployment/deployment-options.md#std-label-node-architecture), or your [read preference](https://www.mongodb.com/docs/manual/core/read-preference/) is set to `secondary` or `nearest`.

    - To ensure consistent scores across subsequent queries, set the `similarity.type` property to `stableTfl` or `boolean` when you index a field as the MongoDB Search [string](https://www.mongodb.com/docs/search/indexes/field-types/string-type.md#std-label-bson-data-types-string) or [autocomplete](https://www.mongodb.com/docs/search/indexes/field-types/autocomplete-type.md#std-label-bson-data-types-autocomplete) type. This forces the [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref), [phrase](https://www.mongodb.com/docs/search/query/operators-collectors/phrase.md#std-label-phrase-ref), [queryString](https://www.mongodb.com/docs/search/query/operators-collectors/querystring.md#std-label-querystring-ref), and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators to use the `stableTfl` or `boolean` similarity algorithm to calculate relevance scores for queries on the indexed field. These algorithms calculate scores consistently across all MongoDB Search nodes. To learn more, see [Score Details.](https://www.mongodb.com/docs/search/query/score/get-details.md#std-label-fts-similarity-algorithms)

- To count search results during pagination, use the [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) option in your initial [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query or in a separate [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) query. This method is more efficient than using the [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count) stage after your [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage.

  The [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) option returns the total number of documents that match your search criteria, so you don't need to use the `count` option in later queries if you are generating paginated results. To keep counting separate from your main `$search` query, use a [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage with the `count` option.

  Counting search results can affect performance. Use the [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) option only when needed, for example, when retrieving search results for the first page.

## Retrieve Point of Reference

To retrieve query results at a certain point, you must provide the point of reference in your [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query. You can retrieve the reference point by using the [`$meta`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta.md#mongodb-expression-exp.-meta) keyword `searchSequenceToken` in the [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) stage after your [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage.

### Syntax

```json
[{
  "$search": {
    "index": "<index-name>",
    "<operator-name>"|"<collector-name>": {
      <operator-specification>|<collector-specification>
    },
    "sort": {
      "score": {
        "$meta": "searchScore"
      }
    },
    ...
  },
  {
    "$project": {
       "paginationToken" : { "$meta" : "searchSequenceToken" }
  },
  ...
}]
```

### Output

The `searchSequenceToken` generates a Base64-encoded token for each document in the results. The length of the token increases with the number of fields specified in the [sort](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref) option of your query. The token isn't tied to a snapshot of the database.

The documents in the results are sorted in the default order, unless you specify the `sort` option in your query. To learn about sorting your results, see [Sort MongoDB Search Results.](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref)

## Search After a Specific Point of Reference

To search after a reference point, you must specify the reference point in your [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query by using the `searchAfter` option with the token generated by `searchSequenceToken`. You can use the token generated by `searchSequenceToken` only when you rerun the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query for which `searchSequenceToken` generated the token. The semantics (search fields and values) of the subsequent [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query in which you use the token must be identical to the query for which `searchSequenceToken` generated the token.

You can use the `searchAfter` option to build a "Next Page" function in your application. For a demonstration of this, see the [example](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-search-before-egs) on this page.

### `searchAfter` Syntax

```json
[{
  "$search": {
    "index": "<index-name>",
    "<operator-name>"|"<collector-name>": {
      <operator-specification>|<collector-specification>
    },
    "searchAfter": "<base64-encoded-token>",
    "sort": {
      "score": {
        "$meta": "searchScore"
      }
    },
    ...
  },
  "$project": {
    "paginationToken" : { "$meta" : "searchSequenceToken" }
  },
  ...
}]
```

### Output

MongoDB Search returns the documents in the results after the specified token. MongoDB Search returns the generated tokens for the documents in the results because you specified the `searchSequenceToken` in the [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) stage after the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage (as shown in line 11). These tokens can be used as a reference point for another query with the same semantics.

The documents in the results are sorted in the default order, unless you specify the `sort` option in your query. To learn about sorting your results, see [Sort MongoDB Search Results.](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref)

## Search Before a Specific Point of Reference

To search before a reference point, you must specify the reference point in your [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query by using the `searchBefore` option with the token generated by `searchSequenceToken`. You can use the token generated by `searchSequenceToken` only when you rerun the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query for which `searchSequenceToken` generated the token. The semantics (search fields and values) of the subsequent [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) query in which you use the token must be identical to the query for which `searchSequenceToken` generated the token.

You can use the `searchBefore` option to build a "Previous Page" function in your application. To do this, combine the following:

- [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage with `searchBefore` option

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

- [toArray()](https://www.mongodb.com/docs/manual/reference/method/cursor.toArray/) and `reverse()` methods.

For a demonstration of this, see the `searchBefore` query [examples](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-search-before-egs) on this page.

### `searchBefore` Syntax

```json
[{
  "$search": {
    "index": "<index-name>",
    "<operator-name>"|"<collector-name>": {
      <operator-specification>|<collector-specification>
    },
    "searchBefore": "<base64-encoded-token>",
    "sort": {
      "score": {
       "$meta": "searchScore"
     }
    },
    ...
  },
  "$project": {
    "paginationToken" : { "$meta" : "searchSequenceToken" }
  },
  ...
}]
```

### `searchBefore` Output

MongoDB Search returns documents in the results preceding the specified token in reverse order. MongoDB Search also returns the generated tokens for the documents in the results because you specified the `searchSequenceToken` in the [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) stage after the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage (as shown in line 11). These tokens can be used as a reference point for another query with the same semantics.

## Examples

The following examples use the [`db.collection.aggregate()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.aggregate.md#mongodb-method-db.collection.aggregate) method to run [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) queries against the [sample\_mflix](https://www.mongodb.com/docs/manual/sample-data/sample-mflix.md#std-label-sample-mflix) database. The first example query demonstrates how to retrieve a point of reference, which you use in the subsequent example queries to retrieve additional results for pages after or before the reference point.

To run these example queries in [`mongosh`:](https://www.mongodb.com/docs/mongodb-shell.md#mongodb-binary-bin.mongosh)

1. Load the [sample\_mflix.movies](https://www.mongodb.com/docs/manual/sample-data/sample-mflix.md#std-label-mflix-movies) collection

2. Create the `pagination-tutorial` index with dynamic mappings. To learn how to create an index, see [Manage MongoDB Search Indexes](https://www.mongodb.com/docs/search/indexes/manage-indexes.md#std-label-ref-create-index-programmatically)

3. Connect to your cluster using [`mongosh`](https://www.mongodb.com/docs/mongodb-shell.md#mongodb-binary-bin.mongosh) and switch to the `sample_mflix` database

**Note:**

By default, MongoDB Search sorts the documents in the results by the relevance score of the documents. If multiple documents in the results have identical scores, MongoDB Search returns arbitrarily ordered results. To return documents in a determined order, the queries specify a unique field, `released`, to sort the results.

### Retrieve Page 1 and Generate Pagination Tokens

#### Retrieve results for the first page and retrieve tokens or a point of reference for subsequent queries.

The sample query uses the following pipeline stages to retrieve results for the first page and retrieve tokens or a point of reference for subsequent queries:

| Pipeline Stage | Description |
| --- | --- |
| [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | Searches for titles that contain `summer` in the `title` field by using the [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) operator.; Sorts the results by the `released` field value in ascending order by using the [sort](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref) option. |
| [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) | Limits the results to `10` documents. |
| [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) | Includes only the `title`, `released`, and `genres` fields from the documents in the results. The query also adds the following fields to each document in the results: `paginationToken`, which is the token that can be used as a point of reference in subsequent queries; `score`, which is the relevance score of the document in the results |

```json
db.movies.aggregate([
  {
    "$search": {
      "index": "pagination-tutorial",
      "text": {
        "path": "title",
        "query": "summer"
      },
      "sort": { "released": 1 }
    }
  },
  {
    "$limit": 10
  },
  {
    "$project": {
      "_id": 0,
      "title": 1,
      "released": 1,
      "genres": 1,
      "paginationToken": { "$meta" : "searchSequenceToken" },
      "score": { "$meta": "searchScore" }
    }
  }
])
```

**Output:**

```json
[
  {
    genres: [ 'Drama' ],
    title: "A Summer at Grandpa's",
    paginationToken: 'CKUdGgJgAA==',
    score: 2.262615203857422
  },
  {
    genres: [ 'Musical', 'Romance' ],
    title: 'Summer Stock',
    released: ISODate('1951-01-22T00:00:00.000Z'),
    paginationToken: 'CJsFGgkpAHw/0HT///8=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Comedy', 'Romance' ],
    title: 'Smiles of a Summer Night',
    released: ISODate('1957-12-23T00:00:00.000Z'),
    paginationToken: 'CKIHGgkpAKDlpaf///8=',
    score: 2.0149309635162354
  },
  {
    genres: [ 'Drama' ],
    title: 'Violent Summer',
    released: ISODate('1959-11-13T00:00:00.000Z'),
    paginationToken: 'CI8JGgkpAJhJh7X///8=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Drama', 'Romance' ],
    title: 'A Summer Place',
    released: ISODate('1959-11-18T00:00:00.000Z'),
    paginationToken: 'CLoJGgkpAGQJobX///8=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Drama' ],
    title: 'The End of Summer',
    released: ISODate('1962-02-01T00:00:00.000Z'),
    paginationToken: 'CK0KGgkpAAzP18X///8=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Drama', 'Romance' ],
    title: 'Summer and Smoke',
    released: ISODate('1962-04-01T00:00:00.000Z'),
    paginationToken: 'CMQKGgkpAECmB8f///8=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Documentary', 'Sport' ],
    title: 'The Endless Summer',
    released: ISODate('1968-08-17T00:00:00.000Z'),
    paginationToken: 'CO4MGgkpAJjH5vX///8=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Comedy', 'Drama', 'Romance' ],
    title: "Summer of '42",
    released: ISODate('1971-04-09T00:00:00.000Z'),
    paginationToken: 'CPQQGgkpAGRgUAkAAAA=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Drama' ],
    title: 'That Certain Summer',
    released: ISODate('1972-11-01T00:00:00.000Z'),
    paginationToken: 'COwRGgkpAPQV0hQAAAA=',
    score: 2.579726457595825
  }
]
```

**Note: Count Search Results**

To count search results during pagination, run a separate [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) query with the [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) option. This returns a metadata document that contains the total count of documents matching your search criteria.

The following sample query gets the total number of documents with the term `summer` in the `title` field:

```json
db.movies.aggregate([
  {
    "$searchMeta": {
      "index": "pagination-tutorial",
      "text": {
        "path": "title",
        "query": "summer"
      },
      "count": {
         "type": "lowerBound",
         "threshold": 5000
      }
    }
  }
])
```

**Output:**

```json
[ { count: { lowerBound: Long("65") } } ]
```

### Retrieve Page 2 Using searchAfter

#### Retrieve results to build a function like "Next Page" in your application.

To retrieve additional results, specify the point of reference after which you want to retrieve the results.

The sample query uses the following pipeline stages to retrieve results for the second page using the token generated by `searchSequenceToken` from the [prior query](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-por-query) for the same term:

| Pipeline Stage | Description |
| --- | --- |
| [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | Searches for titles that contain `summer` in the `title` field by using the [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) operator.; Returns documents after the tenth document in the results by using the `searchAfter` option with the pagination token associated with the tenth document in the results of the query you the query you ran to [Retrieve Page 1 and Generate Pagination Tokens.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-por-query); Sorts the results by the `released` field value in ascending order by using the [sort](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref) option. |
| [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) | Limits the results to `10` documents. |
| [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) | Includes only the `title`, `released`, and `genres` fields from the documents in the results. It also adds the following fields to each document in the results: `paginationToken`, which is the token that can be used as point of reference in subsequent queries; `score`, which is the relevance score of the document in the results |

```json
db.movies.aggregate([
  {
    "$search": {
      "index": "pagination-tutorial",
      "text": {
        "path": "title",
        "query": "summer"
      },
      "searchAfter": "COwRGgkpAPQV0hQAAAA=",
      "sort": { "released": 1 }
    }
  },
  {
    "$limit": 10
  },
  {
    "$project": {
      "_id": 0,
      "title": 1,
      "released": 1,
      "genres": 1,
      "paginationToken" : { "$meta" : "searchSequenceToken" },
      "score": { "$meta": "searchScore" }
    }
  }
])
  
```

**Output:**

```json
[
  {
    genres: [ 'Drama' ],
    title: 'Summer Wishes, Winter Dreams',
    released: ISODate('1974-09-09T00:00:00.000Z'),
    paginationToken: 'CMwSGgkpAECHcCIAAAA=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Drama', 'Thriller' ],
    title: 'Shadows of a Hot Summer',
    released: ISODate('1978-09-01T00:00:00.000Z'),
    paginationToken: 'CPEVGgkpAGw/qz8AAAA=',
    score: 2.0149309635162354
  },
  {
    genres: [ 'Drama' ],
    title: 'Indian Summer',
    released: ISODate('1978-11-01T00:00:00.000Z'),
    paginationToken: 'CNYRGgkpAFhj5UAAAAA=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Drama' ],
    title: 'Indian Summer',
    released: ISODate('1978-11-01T00:00:00.000Z'),
    paginationToken: 'CNsRGgkpAFhj5UAAAAA=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Drama', 'Mystery' ],
    title: 'One Deadly Summer',
    released: ISODate('1983-05-11T00:00:00.000Z'),
    paginationToken: 'COwcGgkpAAjtIGIAAAA=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Comedy' ],
    title: 'Summer Rental',
    released: ISODate('1985-08-09T00:00:00.000Z'),
    paginationToken: 'CL8fGgkpABTypHIAAAA=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Drama', 'Romance' ],
    title: 'Summer',
    released: ISODate('1986-08-29T00:00:00.000Z'),
    paginationToken: 'CO0gGgkpAHCiY3oAAAA=',
    score: 3.5844719409942627
  },
  {
    genres: [ 'Drama', 'Thriller' ],
    title: 'Summer Camp Nightmare',
    released: ISODate('1987-04-17T00:00:00.000Z'),
    paginationToken: 'CNkiGgkpAHQ/CX8AAAA=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Action', 'Crime', 'Drama' ],
    title: 'Cold Summer of 1953',
    released: ISODate('1988-06-01T00:00:00.000Z'),
    paginationToken: 'CNsjGgkpACjVTYcAAAA=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Drama', 'War' ],
    title: 'That Summer of White Roses',
    released: ISODate('1989-07-11T00:00:00.000Z'),
    paginationToken: 'CI0mGgkpALSEc48AAAA=',
    score: 2.0149309635162354
  }
]
```

### Return to Page 1 Using searchBefore

#### Retrieve results to build a function like "Previous Page" in your application.

To retrieve previous results, specify the point of reference before which you want to retrieve the results.

The sample query uses the following pipeline stages to return to results on the first page using the token generated by `searchSequenceToken` from the [prior query](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-after-query) for the same term:

| Pipeline Stage | Description |
| --- | --- |
| [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | Searches for titles that contain `summer` in the `title` field by using the [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) operator.; Returns documents 1 to 10 in the MongoDB Search results by using the `searchBefore` option with the pagination token associated with the eleventh document in the results of the query you ran to [Retrieve Page 2 Using searchAfter.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-after-query); Sorts the results by the `released` field value in ascending order by using the [sort](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref) option. |
| [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) | Limits the results to `10` documents. |
| [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) | Includes only the `title`, `released`, and `genres` fields from the documents in the results. It also adds the following fields to each document in the results: `paginationToken`, which is the token that can be used as a point of reference in subsequent queries; `score`, which is the relevance score of the document in the results |

**Note:**

By default, MongoDB Search returns the results in reverse order for queries that specify tokens to retrieve results before a point of reference. To return documents in-order, the query uses the [toArray()](https://www.mongodb.com/docs/manual/reference/method/cursor.toArray/) and the JavaScript `reverse()` methods.

```json
db.movies.aggregate([
  {
    "$search": {
      "index": "pagination-tutorial",
      "text": {
        "path": "title",
        "query": "summer"
      },
      "searchBefore": "CMwSGgkpAECHcCIAAAA=",
      "sort": { "released": 1 }
    }
  },
  {
    "$limit": 10
  },
  {
    "$project": {
      "_id": 0,
      "title": 1,
      "released": 1,
      "genres": 1,
      "paginationToken" : { "$meta" : "searchSequenceToken" },
      "score": { "$meta": "searchScore" }
    }
  }
]).toArray().reverse()
```

**Output:**

```json
[
  {
    genres: [ 'Drama' ],
    title: "A Summer at Grandpa's",
    paginationToken: 'CKUdGgJgAA==',
    score: 2.262615203857422
  },
  {
    genres: [ 'Musical', 'Romance' ],
    title: 'Summer Stock',
    released: ISODate('1951-01-22T00:00:00.000Z'),
    paginationToken: 'CJsFGgkpAHw/0HT///8=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Comedy', 'Romance' ],
    title: 'Smiles of a Summer Night',
    released: ISODate('1957-12-23T00:00:00.000Z'),
    paginationToken: 'CKIHGgkpAKDlpaf///8=',
    score: 2.0149309635162354
  },
  {
    genres: [ 'Drama' ],
    title: 'Violent Summer',
    released: ISODate('1959-11-13T00:00:00.000Z'),
    paginationToken: 'CI8JGgkpAJhJh7X///8=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Drama', 'Romance' ],
    title: 'A Summer Place',
    released: ISODate('1959-11-18T00:00:00.000Z'),
    paginationToken: 'CLoJGgkpAGQJobX///8=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Drama' ],
    title: 'The End of Summer',
    released: ISODate('1962-02-01T00:00:00.000Z'),
    paginationToken: 'CK0KGgkpAAzP18X///8=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Drama', 'Romance' ],
    title: 'Summer and Smoke',
    released: ISODate('1962-04-01T00:00:00.000Z'),
    paginationToken: 'CMQKGgkpAECmB8f///8=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Documentary', 'Sport' ],
    title: 'The Endless Summer',
    released: ISODate('1968-08-17T00:00:00.000Z'),
    paginationToken: 'CO4MGgkpAJjH5vX///8=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Comedy', 'Drama', 'Romance' ],
    title: "Summer of '42",
    released: ISODate('1971-04-09T00:00:00.000Z'),
    paginationToken: 'CPQQGgkpAGRgUAkAAAA=',
    score: 2.579726457595825
  },
  {
    genres: [ 'Drama' ],
    title: 'That Certain Summer',
    released: ISODate('1972-11-01T00:00:00.000Z'),
    paginationToken: 'COwRGgkpAPQV0hQAAAA=',
    score: 2.579726457595825
  }
]
```

### Jump from Page 2 to Page 5 Using searchAfter and $skip

#### Retrieve results to build a function in your application that allows skipping pages.

To skip results and jump from page 2 to 5, use the token that the `searchSequenceToken` generates to specify the point of reference after which you want to retrieve the results and then skip twenty documents in the results.

The sample query uses the following pipeline stages to jump to results on page 5 by using the token generated by `searchSequenceToken` from the [prior query](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-after-query) for the same term and by using the [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) and [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) stages:

| Pipeline Stage | Description |
| --- | --- |
| [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | Searches for titles that contain `summer` in the `title` field by using the [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) operator.; Sorts the results by the `released` field value in ascending order by using the [sort](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref) option.; Returns documents after the twentieth document specified by using the pagination token generated by the query you ran to [Retrieve Page 2 Using searchAfter.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-after-query) |
| [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) | Skips 20 documents in the results after the specified point of reference, which is the token associated with the twentieth document in the results for the query you ran to [Retrieve Page 2 Using searchAfter.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-sequential-pagination-tutorial-after-query) |
| [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) | Limits the results to `10` documents. |
| [`$project`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project) | Includes only the `title`, `released`, and `genres` fields from the documents in the results. It also adds the following fields to each document in the results: `paginationToken`, which is the token that can be used as a point of reference in subsequent queries; `score`, which is the relevance score of the document in the results |

```json
db.movies.aggregate([
    {
      "$search": {
        "index": "pagination-tutorial",
        "text": {
          "path": "title",
          "query": "summer"
        },
        "searchAfter": "COwRGgkpAPQV0hQAAAA=",
        "sort": { "released": 1 }
      }
    },
    {
      "$skip": 20
    },
    {
      "$limit": 10
    },
    {
      "$project": {
        "_id": 0,
        "title": 1,
        "released": 1,
        "genres": 1,
        "paginationToken" : { "$meta" : "searchSequenceToken" },
        "score": { "$meta": "searchScore" }
      }
    }
])
```

**Output:**

```json
[
  {
    genres: [ 'Drama' ],
    title: 'A Storm in Summer',
    released: ISODate('2000-02-27T00:00:00.000Z'),
    paginationToken: 'CO5FGgkpAChakN0AAAA=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Comedy', 'Romance' ],
    title: 'Wet Hot American Summer',
    released: ISODate('2002-04-11T00:00:00.000Z'),
    paginationToken: 'CKtIGgkpAFBUIu0AAAA=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Comedy', 'Drama', 'Romance' ],
    title: 'Summer Things',
    released: ISODate('2002-10-09T00:00:00.000Z'),
    paginationToken: 'CIpPGgkpAFxzxvAAAAA=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Adventure', 'Drama', 'Family' ],
    title: 'Wolf Summer',
    released: ISODate('2003-02-28T00:00:00.000Z'),
    paginationToken: 'COZWGgkpAGS6ofMAAAA=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Animation', 'Adventure' ],
    title: 'Nasu: Summer in Andalusia',
    released: ISODate('2003-06-26T00:00:00.000Z'),
    paginationToken: 'CNlaGgkpAMxoAfYAAAA=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Drama' ],
    title: 'Spring, Summer, Fall, Winter... and Spring',
    released: ISODate('2004-05-28T00:00:00.000Z'),
    paginationToken: 'CJ5ZGgkpAOjnyPwAAAA=',
    score: 1.8161234855651855
  },
  {
    genres: [ 'Comedy', 'Drama', 'Romance' ],
    title: 'Summer Storm',
    released: ISODate('2004-09-02T00:00:00.000Z'),
    paginationToken: 'CMVfGgkpAMRwvP4AAAA=',
    score: 3.000213623046875
  },
  {
    genres: [ 'Drama' ],
    title: 'Summer in the Golden Valley',
    released: ISODate('2004-10-08T00:00:00.000Z'),
    paginationToken: 'CNNWGgkpALTVdf8AAAA=',
    score: 2.0149309635162354
  },
  {
    genres: [ 'Drama', 'Romance' ],
    title: 'My Summer of Love',
    released: ISODate('2005-07-01T00:00:00.000Z'),
    paginationToken: 'CL5aGgkpAEyxzwQBAAA=',
    score: 2.262615203857422
  },
  {
    genres: [ 'Drama' ],
    title: 'Summer in Berlin',
    released: ISODate('2006-01-05T00:00:00.000Z'),
    paginationToken: 'CPZmGgkpANzclwgBAAA=',
    score: 2.579726457595825
  }
]
```

### Use Facet with the Paginated Results

#### Use searchSequenceToken with MongoDB Search facets.

To group results by using MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref), you must index any `string` field as the `token` type. To run the following query and group the results by the `genres` field in the `movies` collection, your index must resemble the following example:

```json
{
  "mappings": {
    "dynamic": true,
      "fields": {
        "genres": {
          "type": "token"
        }
      }
    }
  }
}
```

The sample query uses the following pipeline stages:

| Pipeline Stage | Description |
| --- | --- |
| [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | Searches for titles that contain `summer` in the `title` field by using the [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector.; Retrieves a count of the number of total movies in the results in each genre by using `facets` option. |
| [`$addFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields.md#mongodb-pipeline-pipe.-addFields) | Adds the `paginationToken` field to store the tokens for each document in the results generated by using the [searchSequenceToken](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-paginate-results-search-sequence-token) option. |
| [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) | Limits the results to `10` documents. |
| [`$facet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet) | Returns the following fields: `docs` field, which contains only the `title`, `released`, and `genres` fields from the documents in the results and the `paginationToken` field.; `meta` field, which contains a count of the total number of movies in the results in each genre that is stored in the `$$SEARCH_META` variable. |

```json
db.movies.aggregate([
    {
      "$search": {
        "index": "pagination-tutorial",
        "facet": {
          "operator": {
            "text": {
              "path": "title",
              "query": "summer"
            } 
          },
          "facets": {
            "genresFacet": {
              "type": "string",
              "path": "genres"
            }
          }
        }
      }
    },
    { 
      "$addFields": {
        "paginationToken" : { "$meta" : "searchSequenceToken" }
      }
    },
    { "$limit": 10 },
    {
      "$facet": {
        "docs": [
          { "$project":
            {
              "_id": 0,
              "title": 1,
              "released": 1,
              "genres": 1,
              "paginationToken" : 1
            }
          }
        ],
        "meta": [
          { "$replaceWith": "$$SEARCH_META" },
          { "$limit": 1 }
        ]
      }
    },
    {
      "$set": {
        "meta": {
          "$arrayElemAt": ["$meta", 0]
        }
      }
    }
])
```

**Output:**

```json
[
    {
      docs: [
        {
          genres: [ 'Drama', 'Romance' ],
          title: 'Summer',
          released: ISODate('1986-08-29T00:00:00.000Z'),
          paginationToken: 'CO0gFf1nZUA='
        },
        {
          genres: [ 'Musical', 'Romance' ],
          title: 'Summer Stock',
          released: ISODate('1951-01-22T00:00:00.000Z'),
          paginationToken: 'CJsFFYADQEA='
        },
        {
          genres: [ 'Drama' ],
          title: 'Violent Summer',
          released: ISODate('1959-11-13T00:00:00.000Z'),
          paginationToken: 'CI8JFYADQEA='
        },
        {
          genres: [ 'Drama' ],
          title: 'Indian Summer',
          released: ISODate('1978-11-01T00:00:00.000Z'),
          paginationToken: 'CNYRFYADQEA='
        },
        {
          genres: [ 'Drama' ],
          title: 'Indian Summer',
          released: ISODate('1978-11-01T00:00:00.000Z'),
          paginationToken: 'CNsRFYADQEA='
        },
        {
          genres: [ 'Comedy' ],
          title: 'Summer Rental',
          released: ISODate('1985-08-09T00:00:00.000Z'),
          paginationToken: 'CL8fFYADQEA='
        },
        {
          genres: [ 'Comedy', 'Drama', 'Romance' ],
          title: 'Summer Things',
          released: ISODate('2002-10-09T00:00:00.000Z'),
          paginationToken: 'CIpPFYADQEA='
        },
        {
          genres: [ 'Adventure', 'Drama', 'Family' ],
          title: 'Wolf Summer',
          released: ISODate('2003-02-28T00:00:00.000Z'),
          paginationToken: 'COZWFYADQEA='
        },
        {
          genres: [ 'Comedy', 'Drama', 'Romance' ],
          title: 'Summer Storm',
          released: ISODate('2004-09-02T00:00:00.000Z'),
          paginationToken: 'CMVfFYADQEA='
        },
        {
          genres: [ 'Drama', 'Romance' ],
          title: 'Summer Palace',
          released: ISODate('2007-04-18T00:00:00.000Z'),
          paginationToken: 'CIRrFYADQEA='
        }
      ],
      meta: {
        count: { lowerBound: Long('65') },
        facet: {
          genresFacet: {
            buckets: [
              { _id: 'Drama', count: Long('48') },
              { _id: 'Romance', count: Long('20') },
              { _id: 'Comedy', count: Long('19') },
              { _id: 'Family', count: Long('7') },
              { _id: 'Adventure', count: Long('5') },
              { _id: 'Crime', count: Long('5') },
              { _id: 'Mystery', count: Long('5') },
              { _id: 'Thriller', count: Long('5') },
              { _id: 'Horror', count: Long('4') },
              { _id: 'Action', count: Long('3') }
            ]
          }
        }
      }
    }
]
```
