I have a search which has multiple criterion.
Each criterion (grouped by should
) has a different weighted score.
ElasticSearch returns a list of results; each with a score - which seems an arbitrary score to me. This is because I can't find a denominator for that score.
My question is - how can I represent each score as a ratio?
Dividing each score by max_score
would not work since it'll show the best match as a 100% match with the search criteria.
The _score
calculation depends on the combination of queries used. For instance, a simple query like:
{ "match": { "title": "search" }}
would use Lucene's TFIDFSimilarity, combining:
term frequency (TF): how many times does the term search
appear in the title
field of this document? The more often, the higher the score
inverse document frequency (IDF): how many times does the term search
appear in the title
field of all documents in the index? The more often, the lower the score
field norm: how long is the title
field? The longer the field, the lower the score. (Shorter fields like title
are considered to be more important than longer fields like body
.)
A query normalization factor. (can be ignored)
On the other hand, a bool
query like this:
"bool": {
"should": [
{ "match": { "title": "foo" }},
{ "match": { "title": "bar" }},
{ "match": { "title": "baz" }}
]
}
would calculate the _score
for each clause which matches, add them together then divide by the total number of clauses (and once again have the query normalization factor applied).
So it depends entirely on what queries you are using.
You can get a detailed explanation of how the _score
was calculated by adding the explain
parameter to your query:
curl localhost:9200/_search?explain -d '
{
"query": ....
}'
My question is - how can I represent each score as a ratio?
Without understanding what you want your query to do it is impossible to answer this. Depending on your use case, you could use the function_score
query to implement your own scoring algorithm.