0

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?

1 Answer 1

1

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"
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.