Elasticsearch - How to normalize score when combining regular query and function_score? Elasticsearch - How to normalize score when combining regular query and function_score? elasticsearch elasticsearch

Elasticsearch - How to normalize score when combining regular query and function_score?


Recently i am working on a problem like this too. I couldn't find any formal documentation about this issue but when i investigate the results with "explain api", it seems like "queryNorm" is not applied to the score directly coming from "functions" field. This means that you can not directly normalize script value.

However, i think i find a little bit tricky solution to this problem. If you combine this function field with a query like you do (match_all query) and give a boost to that query, normalization is working on this query that is, multiplication of this two scores - from normalized query and from script- will give us a total normalization. For a better explanation query will be like:

{"query": {    "bool": {        "should": [            {                "function_score": {                    "query": {"match_all": {"boost":1}},                    "functions": [ {                    "script_score": {                        "script": "<some_script>",                    }}],                    "score_mode": "sum",                    "boost_mode": "multiply"                }            },            {                "match": {                    "message": "this is a test"                }            }        ]    }}}

This answer is not a proper solution to your problem but i think you can play with this query to obtain required result. My suggestion to you is use explain api, try to understand what it is returned, examine the parameters affecting final score and play with script and boost values to get optimized solution.

Btw, "rescore query" may help a lot to obtain that %30-%70 ratio on the final score: Official documentation


As far as I searched, there is no way to get a normalized score out of elastic. You will have to hack it by making two queries. First will be a pilot query (preferably with size 1, but rest all attributes same) and it will fetch you the max_score. Then you can shoot your actual query and use functional_score to normalize the score. Pass the max_score you got as part of pilot query in params to function_score and use it to normalize every score. Refer: This article snippet