I have an ElasticSearch query with a custom script score written in Painless language. For now the ES request looks like this, with the natural ES _score
being totally replaced by a custom scoring from my script:
{
"_source": {
"excludes": [
"field_to_exclude",
]
},
"from": 0,
"size": 100,
"query": {
"script_score": {
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": [
{
"term": {
"field_to_filter": 4
}
}
]
}
},
"script": {
"lang": "painless",
"source": "COMPLEX_PAINLESS_SCRIPT"
}
}
},
"sort": [
{
"price": {
"order": "asc"
}
},
"_score"
]
}
Depending on some parameter from the frontend, I want to be able to still calculate the ES natural scoring separately, and keep this custom scoring to be calculated in another field, and even if possible being used as a secondary sorting criteria.
Is this possible?
I finally figured out. This can actually be done if you use a custom _script
field in the sort
array, along with the _score
field for the natural ES score.
And aside from that, we can keep the custom scoring in a specific field in the response by using script_fields
.
Both the ES requests, depending on the sorting criteria, would look like:
{
"_source": {
"excludes": [
"field_to_exclude",
]
},
"from": 0,
"size": 100,
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": [
{
"term": {
"field_to_filter": 4
}
}
]
}
},
"sort": [
{
"price": {
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
},
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "COMPLEX_PAINLESS_SCRIPT"
},
"order": "desc"
}
}
],
"script_fields": {
"custom_score": {
"script": {
"lang": "painless",
"source": "COMPLEX_PAINLESS_SCRIPT"
}
}
}
}
and
{
"_source": {
"excludes": [
"field_to_exclude",
]
},
"from": 0,
"size": 100,
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": [
{
"term": {
"field_to_filter": 4
}
}
]
}
},
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "COMPLEX_PAINLESS_SCRIPT"
},
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
}
],
"script_fields": {
"fit_score": {
"script": {
"lang": "painless",
"source": "COMPLEX_PAINLESS_SCRIPT"
}
}
}
}