Docs Menu
Docs Home
/
Atlas
/ / / /

Paginate the Results

On Atlas clusters running MongoDB 6.0.13+ or 7.0.5+, use Atlas Search to retrieve your $search query results sequentially after or before a reference point. Use the $search searchAfter or searchBefore options to traverse results in-order and build "Next Page" and "Previous Page" functions in your application.

To retrieve paginated results, perform the following steps:

  1. Create an index on the fields you want to query.

  2. Run a $search query that returns a point of reference. To learn more, see Retrieve Point of Reference.

  3. Use the point of reference in your subsequent $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.

    • To learn more about retrieving results to build a "Previous Page" function, see Search Before a Specific Point of Reference.

    • To jump to a page in your results, combine $skip and $limit with $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:

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

      2. Use $skip to skip the 10 results on Page 4 (Results 31-40) and $limit to limit the results to 10 documents.

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

      Here, using $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 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.

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 ensure deterministic search behavior:

  • Sort your query by a unique field to prevent relevance score ties.

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

  • Sort your query results by an immutable field. Atlas 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, Atlas Search may order the same documents differently.

To learn how to sort your query results by an immutable or unique field, see Sort Atlas Search Results.

If you deployed Search Nodes, consider the following:

  • Avoid sorting the results by searchScore because it can be different across Search Nodes.

  • To calculate searchScore, a host takes into consideration all the documents that exist on it, including deleted documents that have not yet been removed from the index. Since the deletion occurs independently on each host, this might cause changes in searchScore depending on which host the query is routed to.

To support pagination when sorting by searchScore on Search Nodes, upvote this request in the MongoDB Feedback Engine.

To retrieve query results at a certain point, you must provide the point of reference in your $search query. You can retrieve the reference point by using the $meta keyword searchSequenceToken in the $project stage after your $search stage.

searchSequenceToken Syntax
1[{
2 "$search": {
3 "index": "<index-name>",
4 "<operator-name>"|"<collector-name>": {
5 <operator-specification>|<collector-specification>
6 }
7 "sort": {
8 "score": {
9 "$meta": "searchScore", _id:1
10 }
11 }
12 ...
13 },
14 {
15 "$project": {
16 { "paginationToken" : { "$meta" : "searchSequenceToken" } }
17 },
18 ...
19}]

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 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 Atlas Search Results.

To search after a reference point, you must specify the reference point in your $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 query for which searchSequenceToken generated the token. The semantics (search fields and values) of the subsequent $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 on this page.

searchAfter Syntax
1{
2 "$search": {
3 "index": "<index-name>",
4 "<operator-name>"|"<collector-name>": {
5 <operator-specification>|<collector-specification>
6 },
7 "searchAfter": "<base64-encoded-token>",
8 "sort": {
9 "score": {
10 "$meta": "searchScore", _id:1
11 }
12 }
13 ...
14 },
15 "$project": {
16 { "paginationToken" : { "$meta" : "searchSequenceToken" } }
17 },
18 ...
19}

Atlas Search returns the documents in the results after the specified token. Atlas Search returns the generated tokens for the documents in the results because you specified the searchSequenceToken in the $project stage after the $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 Atlas Search Results.

To search before a reference point, you must specify the reference point in your $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 query for which searchSequenceToken generated the token. The semantics (search fields and values) of the subsequent $search query in which you use the token must be identical to the query for which searchSequenceToken generated the token.

You can build a "Previous Page" function in your application using the searchBefore option. To build a "Previous Page" function, combine the following:

For a demonstration of this, see the searchBefore query examples on this page.

searchBefore Syntax
1{
2 "$search": {
3 "index": "<index-name>",
4 "<operator-name>"|"<collector-name>": {
5 <operator-specification>|<collector-specification>
6 },
7 "searchBefore": "<base64-encoded-token>",
8 "sort": {
9 "score": {
10 "$meta": "searchScore", _id:1
11 }
12 }
13 ...
14 },
15 "$project": {
16 { "paginationToken" : { "$meta" : "searchSequenceToken" } }
17 },
18 ...
19}

Atlas Search returns documents in the results preceding the specified token in reverse order. Atlas Search also returns the generated tokens for the documents in the results because you specified the searchSequenceToken in the $project stage after the $search stage (as shown in line 11). These tokens can be used as a reference point for another query with the same semantics.

The following examples use the sample-mflix.movies collection, which has an Atlas Search index named default with dynamic mappings. If you load the collection and create the index, you can run the following queries against the collection.

The queries demonstrate how to retrieve a point of reference, which you then use in the subsequent queries to retrieve additional results for the same term before and after the specified point of reference.

This examples demonstrate how to do the following tasks:

  1. Retrieve Page 1 and Generate Pagination Tokens

  2. Retrieve Page 2 Using searchAfter

  3. Return to Page 1 Using searchBefore

  4. Jump from Page 2 to Page 5 Using searchAfter and $skip

  5. Use Facet with the Paginated Results

Note

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

Back

count