Skip to content

Commit a27205a

Browse files
Add documenation about script rescorer
PR #74274 introduced a new rescorer based on script. This adds a documentation for this rescorer.
1 parent 6d21904 commit a27205a

File tree

2 files changed

+204
-123
lines changed

2 files changed

+204
-123
lines changed

docs/reference/elasticsearch/rest-apis/filter-search-results.md

Lines changed: 0 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ You can use two methods to filter search results:
1212
* Use a boolean query with a `filter` clause. Search requests apply [boolean filters](/reference/query-languages/query-dsl/query-dsl-bool-query.md) to both search hits and [aggregations](/reference/aggregations/index.md).
1313
* Use the search API’s `post_filter` parameter. Search requests apply [post filters](#post-filter) only to search hits, not aggregations. You can use a post filter to calculate aggregations based on a broader result set, and then further narrow the results.
1414

15-
You can also [rescore](#rescore) hits after the post filter to improve relevance and reorder results.
16-
17-
18-
1915
## Post filter [post-filter]
2016

2117
When you use the `post_filter` parameter to filter search results, the search hits are filtered after the aggregations are calculated. A post filter has no impact on the aggregation results.
@@ -125,122 +121,3 @@ GET /shirts/_search
125121
2. The `colors` agg returns popular colors for shirts by Gucci.
126122
3. The `color_red` agg limits the `models` sub-aggregation to **red** Gucci shirts.
127123
4. Finally, the `post_filter` removes colors other than red from the search `hits`.
128-
129-
130-
131-
## Rescore filtered search results [rescore]
132-
133-
Rescoring can help to improve precision by reordering just the top (eg 100 - 500) documents returned by the [`query`](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search) and [`post_filter`](#post-filter) phases, using a secondary (usually more costly) algorithm, instead of applying the costly algorithm to all documents in the index.
134-
135-
A `rescore` request is executed on each shard before it returns its results to be sorted by the node handling the overall search request.
136-
137-
Currently the rescore API has only one implementation: the query rescorer, which uses a query to tweak the scoring. In the future, alternative rescorers may be made available, for example, a pair-wise rescorer.
138-
139-
::::{note}
140-
An error will be thrown if an explicit [`sort`](/reference/elasticsearch/rest-apis/sort-search-results.md) (other than `_score` in descending order) is provided with a `rescore` query.
141-
::::
142-
143-
144-
::::{note}
145-
when exposing pagination to your users, you should not change `window_size` as you step through each page (by passing different `from` values) since that can alter the top hits causing results to confusingly shift as the user steps through pages.
146-
::::
147-
148-
149-
150-
### Query rescorer [query-rescorer]
151-
152-
The query rescorer executes a second query only on the Top-K results returned by the [`query`](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search) and [`post_filter`](#post-filter) phases. The number of docs which will be examined on each shard can be controlled by the `window_size` parameter, which defaults to 10.
153-
154-
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`.
155-
156-
For example:
157-
158-
```console
159-
POST /_search
160-
{
161-
"query" : {
162-
"match" : {
163-
"message" : {
164-
"operator" : "or",
165-
"query" : "the quick brown"
166-
}
167-
}
168-
},
169-
"rescore" : {
170-
"window_size" : 50,
171-
"query" : {
172-
"rescore_query" : {
173-
"match_phrase" : {
174-
"message" : {
175-
"query" : "the quick brown",
176-
"slop" : 2
177-
}
178-
}
179-
},
180-
"query_weight" : 0.7,
181-
"rescore_query_weight" : 1.2
182-
}
183-
}
184-
}
185-
```
186-
187-
The way the scores are combined can be controlled with the `score_mode`:
188-
189-
| Score Mode | Description |
190-
| --- | --- |
191-
| `total` | Add the original score and the rescore query score. The default. |
192-
| `multiply` | Multiply the original score by the rescore query score. Usefulfor [`function query`](/reference/query-languages/query-dsl/query-dsl-function-score-query.md) rescores. |
193-
| `avg` | Average the original score and the rescore query score. |
194-
| `max` | Take the max of original score and the rescore query score. |
195-
| `min` | Take the min of the original score and the rescore query score. |
196-
197-
198-
### Multiple rescores [multiple-rescores]
199-
200-
It is also possible to execute multiple rescores in sequence:
201-
202-
```console
203-
POST /_search
204-
{
205-
"query" : {
206-
"match" : {
207-
"message" : {
208-
"operator" : "or",
209-
"query" : "the quick brown"
210-
}
211-
}
212-
},
213-
"rescore" : [ {
214-
"window_size" : 100,
215-
"query" : {
216-
"rescore_query" : {
217-
"match_phrase" : {
218-
"message" : {
219-
"query" : "the quick brown",
220-
"slop" : 2
221-
}
222-
}
223-
},
224-
"query_weight" : 0.7,
225-
"rescore_query_weight" : 1.2
226-
}
227-
}, {
228-
"window_size" : 10,
229-
"query" : {
230-
"score_mode": "multiply",
231-
"rescore_query" : {
232-
"function_score" : {
233-
"script_score": {
234-
"script": {
235-
"source": "Math.log10(doc.count.value + 2)"
236-
}
237-
}
238-
}
239-
}
240-
}
241-
} ]
242-
}
243-
```
244-
245-
The first one gets the results of the query then the second one gets the results of the first, etc. The second rescore will "see" the sorting done by the first rescore so it is possible to use a large window on the first rescore to pull documents into a smaller window for the second rescore.
246-
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
mapped_pages:
3+
- https://www.elastic.co/guide/en/elasticsearch/reference/current/rescore-search-results.html
4+
applies_to:
5+
stack: all
6+
---
7+
8+
# Rescore search results [rescore-search-results]
9+
10+
Rescoring can help to improve precision by reordering just the top
11+
(e.g. 100 - 500) documents returned by initial retrieval phase
12+
(query, knn search) by using a secondary (usually more costly) algorithm,
13+
instead of applying the costly algorithm to all documents in the index.
14+
15+
A `rescore` request is executed on each shard before it returns its results
16+
to be sorted by the node handling the overall search request.
17+
18+
The rescore API has 3 options:
19+
20+
1. `query` rescorer that executes a provided `rescore_query` on the top documents
21+
2. `script` rescorer that uses a script to modify the scores of the top documents
22+
3. `learning_to_rank` rescorer that uses an LTR model to re-rank the top documents
23+
24+
All rescores have the `window_size` parameter that controls how many top
25+
documents will be considered for rescoring. The default is 10.
26+
27+
::::{note}
28+
When implementing pagination, keep the `window_size` consistent across pages.
29+
Changing it while advancing through results (by using different `from` values)
30+
can cause the top hits to shift, leading to a confusing user experience.
31+
::::
32+
33+
### Query Rescorer [query-rescorer]
34+
35+
The query rescorer executes a second query only on the top documents returned
36+
from the previous phase. The number of docs which is examined on each shard
37+
can be controlled by the `window_size` parameter.
38+
39+
By default, the scores from the original query and the rescore query are combined
40+
linearly to produce the final `_score` for each document.
41+
The relative importance of the original query and of the rescore query can be
42+
controlled with the `query_weight` and `rescore_query_weight` respectively.
43+
Both default to `1`.
44+
45+
For example:
46+
47+
```console
48+
POST /_search
49+
{
50+
"query" : {
51+
"match" : {
52+
"message" : {
53+
"operator" : "or",
54+
"query" : "the quick brown"
55+
}
56+
}
57+
},
58+
"rescore" : {
59+
"window_size" : 10,
60+
"query" : {
61+
"rescore_query" : {
62+
"match_phrase" : {
63+
"message" : {
64+
"query" : "the quick brown",
65+
"slop" : 2
66+
}
67+
}
68+
},
69+
"query_weight" : 0.7,
70+
"rescore_query_weight" : 1.2
71+
}
72+
}
73+
}
74+
```
75+
76+
::::{note}
77+
An error will be thrown if an explicit [`sort`](/reference/elasticsearch/rest-apis/sort-search-results.md)
78+
(other than `_score` in descending order) is provided with a `rescore` query.
79+
::::
80+
81+
82+
The way the scores are combined can be controlled with the `score_mode`:
83+
84+
| Score Mode | Description |
85+
| --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
86+
| `total` | Add the original score and the rescore query score. The default. |
87+
| `multiply` | Multiply the original score by the rescore query score. Useful for [`function query`](/reference/query-languages/query-dsl/query-dsl-function-score-query.md) rescores. |
88+
| `avg` | Average the original score and the rescore query score. |
89+
| `max` | Take the max of original score and the rescore query score. |
90+
| `min` | Take the min of the original score and the rescore query score. |
91+
92+
### Script rescorer [script-rescorer]
93+
94+
`script` rescorer uses a script to rescore the top documents returned
95+
from the previous phase. The script has access to the original score as well
96+
as values of document fields.
97+
98+
For example, the following script rescores documents based on the document's
99+
original query score and the value of field `num_likes`:
100+
101+
```console
102+
POST /_search
103+
{
104+
"query" : {
105+
"match" : {
106+
"message" : {
107+
"operator" : "or",
108+
"query" : "the quick brown"
109+
}
110+
}
111+
},
112+
"rescore" : {
113+
"window_size" : 10,
114+
"script" : {
115+
"script" : {
116+
"source": "doc['num_likes'].value * params.multiplier + _score",
117+
"parameters": {
118+
"multiplier": 0.1
119+
}
120+
}
121+
}
122+
}
123+
}
124+
```
125+
126+
### Learning to rank rescorer [learning-to-rank-rescorer]
127+
`learning_to_rank` uses an LTR model to rescore the top documents. You must
128+
provide the `model_id` of a deployed model, as well as any named parameters
129+
required by the query templates for features used by the model.
130+
131+
```console
132+
GET my-index/_search
133+
{
134+
"query": { <1>
135+
"multi_match": {
136+
"fields": ["title", "content"],
137+
"query": "the quick brown fox"
138+
}
139+
},
140+
"rescore": {
141+
"learning_to_rank": {
142+
"model_id": "ltr-model",
143+
"params": {
144+
"query_text": "the quick brown fox"
145+
}
146+
},
147+
"window_size": 100
148+
}
149+
}
150+
```
151+
152+
### Multiple rescores [multiple-rescores]
153+
154+
You can apply multiple rescoring operations in sequence. The first rescorer
155+
works on the top documents from the initial retrieval phase, while the second
156+
rescorer works on the output of the first rescorer, and so on. A common practice
157+
is to use a larger window for the first rescorer and smaller windows for more
158+
expensive subsequent rescorers.
159+
160+
```console
161+
POST /_search
162+
{
163+
"query": {
164+
"match": {
165+
"message": {
166+
"operator": "or",
167+
"query": "the quick brown"
168+
}
169+
}
170+
},
171+
"rescore": [
172+
{
173+
"window_size": 10,
174+
"query": {
175+
"rescore_query": {
176+
"match_phrase": {
177+
"message": {
178+
"query": "the quick brown",
179+
"slop": 2
180+
}
181+
}
182+
},
183+
"query_weight": 0.7,
184+
"rescore_query_weight": 1.2
185+
}
186+
},
187+
{
188+
"window_size": 5,
189+
"query": {
190+
"score_mode": "multiply",
191+
"rescore_query": {
192+
"function_score": {
193+
"script_score": {
194+
"script": {
195+
"source": "Math.log10(doc.count.value + 2)"
196+
}
197+
}
198+
}
199+
}
200+
}
201+
}
202+
]
203+
}
204+
```

0 commit comments

Comments
 (0)