Problem
What is a good alternative query if I need both a rescore and a sort? I know combining both is not supported (the rescore query is not executed with the Elasticsearch 5.4 version I am using, and the documentation states that it raises an exception with Elasticsearch 6.x) but I can't come up with a single query that would approach the behavior I am expecting.
Example
Let's say the documents in my index represent books with fields title
, description
and genre
. I would like to have a primary query to match on the title
field, then a rescore query to match on the description
field only for the top 500 documents, and finally a sort that involves both the genre
field (to sort the results based on a custom ordering of the different genre values) and the rescored score.
I first tried using the following query:
{
"query": {
"match": {
"title": "birds"
}
},
"rescore": {
"query": {
"query_weight": 1.0,
"rescore_query": {
"match": {
"description": "colorful"
}
},
"rescore_query_weight": 1.0
},
"window_size": 500
},
"sort": [
{
"_script": {
"order": "asc",
"script": {
"params": {
"Fantasy": 0,
"Thriller": 1,
"Detective": 2
},
"source": "params[doc['genre.keyword'].value]"
},
"type": "number"
}
},
{
"_score": "desc"
}
]
}
Not satisfactory workaround
Because rescore and sort are not compatible, I ended up using three different rescore-only queries, one for each genre (Fantasy, Thriller and Detective) and concatenating the results in the expected order. But this solution has several drawbacks:
- it's more time consuming as I send several queries to Elasticsearch
- it's harder to make use of Elasticsearch capabilities for pagination of the results
- it requires code outside Elasticsearch
In my real-life use case, I don't want to bring the rescore query content to the primary query and use sort only, because my primary query returns many documents and the rescore query takes too much time to calculate scores on every returned document...
Thank you in advance for any advice on how to deal with rescoring and sorting at the same time!