All Products
Search
Document Center

OpenSearch:Document sorting practices in OpenSearch

Last Updated:Apr 01, 2026

OpenSearch ranks search results using two cooperating mechanisms: a sort clause that defines the final field-and-score ordering, and sort policies that define how relevance scores are calculated through a two-phase pipeline called rough sort and fine sort.

How scoring works

OpenSearch scoring runs in two stages:

  1. Rough sort (FirstRank): After documents are retrieved by the query clause and filtered by the filter clause, rough sort scores all matching documents using the rough sort expression.

  2. Fine sort (SecondRank): The top N documents from rough sort are re-scored using the fine sort expression. The final sort policy score is based on the fine sort result.

This two-phase design exists so that expensive fine sort expressions run only on a small candidate set, not on every matched document. The 10,000-point base added at each stage transition separates documents that reached fine sort from those that did not — which is why debug output shows scores like 10000.2259 rather than the raw expression value.

Score calculation rules:

Sort policy configurationScore formulaMaximum score
Rough sort only10,000 + rough sort expression result20,000 (capped)
Fine sort only10,000 + fine sort expression resultNo limit
Both rough and fine sortDocuments reaching fine sort: 10,000 + fine sort result; documents that only pass rough sort: 10,000 + rough sort result20,000 (capped)

Sort clause and sort policies

The sort clause controls the final ordering of documents — similar to the ORDER BY clause in SQL. List sort fields and RANK in priority order, separated by semicolons. Prefix each entry with - for descending order or + for ascending order. RANK represents the final score from the sort policy.

sort=-create_time;-RANK

This clause sorts by create_time descending first, then by the sort policy score descending for documents with the same create_time.

Important

By default, if no sort clause is configured, the system applies -RANK automatically. If you configure a sort clause, -RANK is not added automatically — include it explicitly whenever you want sort policy scores to influence ranking.

ScenarioBehavior
No sort clauseSystem applies -RANK
Sort clause without RANKSort policy score has no effect
Sort clause with -RANKSort policy score applies as a tiebreaker or primary criterion

To configure the expressions used in rough sort and fine sort, see Configure sort policies.

Example: sort clause with a two-field sort

Consider an application with the following schema:

FieldTypeIndex
idintKeyword
nametextGeneral index for Chinese
ageintKeyword

The rough sort policy uses static_bm25(). The fine sort policy uses text_relevance(name).

Configure the sort clause:

sort=age;-RANK

This sorts documents first by age ascending. For documents with the same age, it sorts by the sort policy score descending.

Turn on Show Sort Details to inspect the score breakdown. The output looks similar to:

image

The score 13,10000.2259030193 breaks down as:

  • 13 — the value of the age field

  • 10000.2259030193 — the final sort policy score

The sort formula behind that score:

FirstRank:
expression[static_bm25()], result[0.496452].
SecondRank:
expression[text_relevance(name)], result[0.225903].

The rough sort policy for the name field is configured as shown:

image

The fine sort policy for the name field is configured as shown:

image

How the final score 10000.2259030193 is calculated: the document ranked in the top 200 based on rough sort (score: 0.496452), so it entered fine sort. At that transition, OpenSearch discards the rough sort score and adds 10,000 as a base. The fine sort expression text_relevance(name) produced 0.225903, giving a final score of 10000 + 0.225903 = 10000.2259030193.

Sort policies

What's next