ES 6.2 Multiple Function Scores/Boost Modes

I'm trying to add the Page Rank to the score of a document, adjusted by date decay. I know I can multiply the Rank and Date Decay together with a "score_mode": "multiply", but I have other factors that I want summed, and I'm not sure how to break up the different ways I want portions scored and collected.

For example, lets say I'd like score to be:
score = _score + hierarchical_weight + rank*decay

I have only be able to figure out up this point
score = _score + hierarchical_weight + rank + decay

As demonstrated with the following query

{
  "query": {
    "function_score": {
      "functions": [
        {
          "field_value_factor": {
            "field": "hierarchical_weight",
            "factor": 1,
            "modifier": "none",
          }
        },
        {
          "field_value_factor": {
            "field": "rank",
            "factor": 1,
            "modifier": "none",
          }
        },
        {
          "exp": {
            "date": {
              "origin": "now",
              "scale": "365d",
              "decay": 0.5
            }
          },
        }
      ],
      "score_mode": "sum",
      "boost_mode": "sum",
      "query": {
        "bool": {
          "should": [
            {
              "match": {[. . . truncated . . .]

Any help would be greatly appreciated

You could nest a function score query inside of another function score query, where the inner function score query uses score_mode multiply and the outer score_mode sum (or in this case a boost_mode sum). It's not pretty, and it may not be fast on larger datasets, but it works:

{
  "query": {
    "function_score": {
      "functions": [
        {
          "field_value_factor": {
            "field": "hierarchical_weight",
            "factor": 1,
            "modifier": "none"
          }
        }
      ],
      "score_mode": "sum",
      "boost_mode": "sum",
      "query": {
        "function_score": {
          "query": {
            "bool": {
              "should": [
                {
                  "match": {
                    "foo": "bar"
                  }
                }
              ]
            }
          },
          "functions": [
            {
              "field_value_factor": {
                "field": "rank",
                "factor": 1,
                "modifier": "none"
              }
            },
            {
              "exp": {
                "date": {
                  "origin": "now",
                  "scale": "365d",
                  "decay": 0.5
                }
              }
            }
          ],
          "score_mode": "multiply",
          "boost_mode": "sum"
        }
      }
    }
  }
}

Having said that, work is under way to make custom score calculation more flexible in Elasticsearch in the future. You can follow that work here: https://github.com/elastic/elasticsearch/issues/23850

1 Like

Thank you for the reply, and the very informative link on the issue; it explains why it was so hard to find information on how to do this on my own.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.