---
title: Rescore search results
description: You can use the Search API's rescore parameter￼to rescore the top documents returned by a search request. Rescoring can help improve precision by reordering...
url: https://www.elastic.co/docs/reference/elasticsearch/rest-apis/rescore-search-results
products:
  - Elasticsearch
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available
---

# Rescore search results
You can use the Search API's [`rescore` parameter](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search#operation-search-body-application-json-rescore)￼to rescore the top documents returned by a search request. Rescoring can help improve precision by reordering just the top (e.g. 100 - 500) documents returned by the initial retrieval phase (query, knn search) by using a secondary (usually more costly) algorithm, instead of applying the costly algorithm to all documents in the index.

## How `rescore` works

A `rescore` request is executed on each shard before it returns its results
to be sorted by the node handling the overall search request.
The rescore API has 3 options:
1. `query` rescorer that executes a provided `rescore_query` on the top documents
2. `script` rescorer that uses a script to modify the scores of the top documents
3. `learning_to_rank` rescorer that uses an LTR model to re-rank the top documents

All rescores have the `window_size` parameter that controls how many top
documents will be considered for rescoring. The default is 10.
<note>
  When implementing pagination, keep the `window_size` consistent across pages.
  Changing it while advancing through results (by using different `from` values)
  can cause the top hits to shift, leading to a confusing user experience.
</note>


## Query Rescorer

The query rescorer executes a second query only on the top documents returned
from the previous phase. The number of docs which is examined on each shard
can be controlled by the `window_size` parameter.
By default, the scores from the original query and the rescore query are combined
linearly to produce the final `_score` for each document.
The relative importance of the original query and of the rescore query can be
controlled with the `query_weight` and `rescore_query_weight` respectively.
Both default to `1`.
For example:
```json

{
   "query" : {
      "match" : {
         "message" : {
            "operator" : "or",
            "query" : "the quick brown"
         }
      }
   },
   "rescore" : {
      "window_size" : 10,
      "query" : {
         "rescore_query" : {
            "match_phrase" : {
               "message" : {
                  "query" : "the quick brown",
                  "slop" : 2
               }
            }
         },
         "query_weight" : 0.7,
         "rescore_query_weight" : 1.2
      }
   }
}
```

<note>
  An error will be thrown if an explicit [`sort`](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/sort-search-results)
  (other than `_score` in descending order) is provided with a `rescore` query.
</note>

The way the scores are combined can be controlled with the `score_mode`:

| Score Mode | Description                                                                                                                                                                                     |
|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `total`    | Add the original score and the rescore query score. The default.                                                                                                                                |
| `multiply` | Multiply the original score by the rescore query score. Useful for [`function query`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-function-score-query) rescores. |
| `avg`      | Average the original score and the rescore query score.                                                                                                                                         |
| `max`      | Take the max of original score and the rescore query score.                                                                                                                                     |
| `min`      | Take the min of the original score and the rescore query score.                                                                                                                                 |


## Script rescorer

<applies-to>
  - Elastic Stack: Generally available since 9.2
</applies-to>

`script` rescorer uses a script to rescore the top documents returned
from the previous phase. The script has access to the original score as well
as values of document fields.
For example, the following script rescores documents based on the document's
original query score and the value of field `num_likes`:
```json

{
   "query" : {
      "match" : {
         "message" : {
            "operator" : "or",
            "query" : "the quick brown"
         }
      }
   },
   "rescore" : {
      "window_size" : 10,
      "script" : {
         "script" : {
            "source": "doc['num_likes'].value * params.multiplier + _score",
            "parameters": {
               "multiplier": 0.1
            }
         }
      }
   }
}
```


## Learning to rank rescorer

`learning_to_rank` uses an LTR model to rescore the top documents. You must
provide the `model_id` of a deployed model, as well as any named parameters
required by the query templates for features used by the model.
```json

{
  "query": {
    "multi_match": {
      "fields": ["title", "content"],
      "query": "the quick brown fox"
    }
  },
  "rescore": {
    "learning_to_rank": {
      "model_id": "ltr-model",
      "params": {
        "query_text": "the quick brown fox"
      }
    },
    "window_size": 100
  }
}
```


## Multiple rescores

You can apply multiple rescoring operations in sequence. The first rescorer
works on the top documents from the initial retrieval phase, while the second
rescorer works on the output of the first rescorer, and so on. A common practice
is to use a larger window for the first rescorer and smaller windows for more
expensive subsequent rescorers.
```json

{
  "query": {
    "match": {
      "message": {
        "operator": "or",
        "query": "the quick brown"
      }
    }
  },
  "rescore": [
    {
      "window_size": 10,
      "query": {
        "rescore_query": {
          "match_phrase": {
            "message": {
              "query": "the quick brown",
              "slop": 2
            }
          }
        },
        "query_weight": 0.7,
        "rescore_query_weight": 1.2
      }
    },
    {
      "window_size": 5,
      "query": {
        "score_mode": "multiply",
        "rescore_query": {
          "function_score": {
            "script_score": {
              "script": {
                "source": "Math.log10(doc.count.value + 2)"
              }
            }
          }
        }
      }
    }
  ]
}
```