Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elasticsearch order by a certain field value first

I'd like to apply a certain sort to a query, it should sort my documents by a single value first then all the others. I need to achieve something like the ORDER BY CASE WHEN in MySQL, but I couldn't find how to do it.

Each element in the index in Elastic has the following structure:

{
    "id": 123,
    "name": "Title",
    "categories": ["A", "B", "C"],
    "price": 100,
    "city": "London",
    "country": "United Kingdom",
    "status": 1
}

I do the following query:

{
    "fields": [],
    "sort": [{"price": {"order": "asc"}}],
    "size": 0,
    "query": {
        "query_string": {
            "query": "status:1 AND country:'United Kingdom'"
        }
    },
    "aggs": {
        "id": {
            "terms": {
                "field": "id",
                "size": 10
            }
        }
    }
}

So by sorting the column city with value "Liverpool" first and considering the following example:

{"id": 1, "name": "Test", "categories": ["A", "B", "C"], "price": 100, "city": "London", "country": "United Kingdom", "status": 1 }
{"id": 2, "name": "Sample", "categories": ["A", "D", "F"], "price": 200, "city": "Manchester", "country": "United Kingdom", "status": 1 }
{"id": 3, "name": "Title", "categories": ["X", "Y", "Z"], "price": 1000, "city": "Liverpool", "country": "United Kingdom", "status": 1 }

I expect to have as output the following id: 3, 1, 2.

How can I change my query to obtain this behaviour?

UPDATE: The version is 1.7.2

like image 670
Fabio Cicerchia Avatar asked Sep 29 '16 05:09

Fabio Cicerchia


People also ask

How do I select a specific field in Elasticsearch?

There are two recommended methods to retrieve selected fields from a search query: Use the fields option to extract the values of fields present in the index mapping. Use the _source option if you need to access the original data that was passed at index time.

How do I sort data in Elasticsearch?

Sort mode optioneditPick the highest value. Use the sum of all values as sort value. Only applicable for number based array fields. Use the average of all values as sort value.

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.

How does elastic search sort work?

Elasticsearch comes with a good default out of the box. 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.


1 Answers

You should use "_script" for 1.7 version. Try this:

1.7:

"query" : {
    ....
},
"sort" : {
    "_script" : {
        "script" : "doc['city'].value == 'Liverpool' ? 1 : 0",
        "type" : "number",
        "order" : "desc"
    },
    "example_other_field_order":"asc",
    "next_example_field_order":"asc"
}

For latest version of elasticsearch (>= 5.5) check this doc.

like image 109
Adrian Avatar answered Oct 14 '22 17:10

Adrian