Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom sorting in Elasticsearch

Does anyone know if it's possible to custom sort in elasticsearch?

I have a sort on the category field. Which groups all of the records together by category. This works great.

However could you then give the sort a list e.g cars, books, food.

It would then show the cars first, then books and finally food?

like image 206
Brian Avatar asked Aug 30 '17 14:08

Brian


People also ask

How do I sort data in Elasticsearch?

You can sort Elasticsearch results using the sort keyword. The sort query requires you to provide a field under which to sort. Elasticsearch does not support sorting on fields of type text.

What is the default sort order in Elasticsearch?

In Elasticsearch, the relevance score is represented by the floating-point number returned in the search results as the _score, so the default sort order is _score descending.

How does Elasticsearch sorting work?

It sorts the results by relevance to the search query term, most relevant first. Elasticsearch measures the relevance score as a floating-point number called _score, and orders results in the descending order of their _score values.

What is _score in Elasticsearch?

The _score in Elasticsearch is a way of determining how relevant a match is to the query. The default scoring function used by Elasticsearch is actually the default built in to Lucene which is what Elasticsearch runs under the hood.


2 Answers

You can use a function_score query, something like this:

{
    "query": {
        "function_score": {
          "query": { "match_all": {} },
          "boost": "5", 
          "functions": [
              {
                  "filter": { "match": { "category": "cars" } },
                  "weight": 100
              },
              {
                  "filter": { "match": { "category": "books" } },
                  "weight": 50
              },
              {
                  "filter": { "match": { "category": "food" } },
                  "weight": 1
              }
          ],
          "score_mode": "max",
          "boost_mode": "replace"
        }
    }
}

Where you, of course, put whichever query you are using now instead of the match_all query, and leave off the sort (the default is by score, which is what you want here).

This is replacing the score elasticsearch normally generates, with a custom score for each category. You could experiment with other boost_mode in order to have a reasonable ranking within the categories. In case you need to understand what is happening with the scoring, you can add "explain": true to the query at the top level.

like image 60
dshockley Avatar answered Oct 03 '22 15:10

dshockley


You can use custom script for your own scoring.

More details at in Script Based Sorting section: https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-request-sort.html

like image 26
Ansaldos Avatar answered Oct 03 '22 15:10

Ansaldos