Search code examples
luceneelasticsearchbonsai-elasticsearch

What's the denominator for ElasticSearch scores?


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.


Solution

  • 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.