Home > database >  Relevance Scores and Sorting with ElasticSearch
Relevance Scores and Sorting with ElasticSearch

Time:09-17

I am trying to combine both relevance score and sorting by another field and am not sure how to go about it.

My documents have a number of text fields I want to search for a term against. The term may appear in a variety of fields in the document.

I am using the following to do that basic filter:

  "query_string": {
    "query": "Burger",
    "default_field": "*"
  }
}

I also have a field popularityScore that measures the popularity of a document. I tried sorting by that:

  "query": {
    "query_string": {
      "query": "Burger",
      "default_field": "*"
    }
  },
  "sort": [
    {
      "popularityScore": {
        "order": "desc"
      }
    }
  ]
}

By doing that the relevance of the query becomes irrelevant and without it a small deviation in relevance can cause very popular documents to show up lower. Is there a way I can either combine popularityScore and relevance OR cap one (e.g. only return relevance > x and then sort those)?

CodePudding user response:

You can use field function_score and field_value_factor

Query

{
  "query": {
    "function_score": {
      "query": {
        "query_string": {
          "query": "Burger",
          "default_field": "*"
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "popularityScore",
            "factor": 1.2,
            "modifier": "sqrt",
            "missing": 1
          }
        }
      ],
      "boost_mode": "sum"
    }
  }
}

Result

"hits" : [
      {
        "_index" : "index35",
        "_type" : "_doc",
        "_id" : "gLyT6XsBQ6SrO4ATYGUQ",
        "_score" : 3.9282646,
        "_source" : {
          "title" : "Burger",
          "popularityScore" : 12
        }
      },
      {
        "_index" : "index35",
        "_type" : "_doc",
        "_id" : "fryS6XsBQ6SrO4AT_WXV",
        "_score" : 3.5976331,
        "_source" : {
          "title" : "Burger",
          "popularityScore" : 10
        }
      },
      {
        "_index" : "index35",
        "_type" : "_doc",
        "_id" : "f7yT6XsBQ6SrO4ATC2WI",
        "_score" : 3.231918,
        "_source" : {
          "title" : "Burger",
          "popularityScore" : 8
        }
      }
    ]

The field_value_factor function allows you to use a field from a document to influence the score.

function_score = sqrt(1.2 * doc['popularityScore'].value)"

document_score = function_score query_score.

You can choose "modifier" based on how much you want to affect the query score. You will find multiple options for this in field_value_factor documentation.

  • Related