Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort elastic search results by score + boost + field?

Given an index of books that have a title, an author, and a description, I'd like the resulting search results to be sorted this way:

  1. all books that match the title sorted by downloads (a numeric value)
  2. all books that match on author sorted by downloads
  3. all books that match on description sorted by downloads

I use the search query below, but the problem is that each entry has a different score thus making sorting by downloads irrelevant.

e.g. when the search term is 'sorting' - title: 'sorting in elastic search' will score higher than title: 'postgresql sorting is awesome' (because of the word position).

query = QueryBuilders.multiMatchQuery(queryString, "title^16", "author^8", "description^4")

elasticClient.prepareSearch(Index)
      .setTypes(Book)          
      .setQuery(query)
      .addSort(SortBuilders.scoreSort())
      .addSort(SortBuilders.fieldSort("downloads").order(SortOrder.DESC))

How do I construct my query so that I could get the desired book sorting?

I use standard analysers and I need to the search query to be analysed, also I will have to handle multi-word search query strings.

Thx.

like image 543
vrepsys Avatar asked Mar 18 '23 12:03

vrepsys


1 Answers

What you need here is a way to compute score based on three weighted field and a numeric field. Sort will sum the score obtained from both , due to which if either one of them is too large , it will supersede the other. Hence a better approach would be to multiple downloads with the score obtained by the match. So i would recommend function score query -

{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "sorting",
          "fields": [
            "title^16",
            "author^8",
            "description^4"
          ]
        }
      },
      "function": [
        {
          "field_value_factor": {
            "field": "downloads"
          }
        }
      ],
      "boost_mode": "multiply"
    }
  }
}

This will compute the score based on all three fields. And then multiply that score with the value in download field to get the final score. The multiply boost_mode decides how the value computed by functions are clubbed together with the score computed by query.

like image 142
Vineeth Mohan Avatar answered Mar 20 '23 03:03

Vineeth Mohan