Search code examples
sortingelasticsearchelasticsearch-queryelasticsearch-py

ElasticSearch not sorting results


I'm trying to sort the results based on a numeric field,

Here is my mapping:

{
  "elasticie": {
    "mappings": {
      "properties": {
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "number": {
          "type": "long"
        }
      }
    }
  }
}

I'm using Python, and this is my testing data:

data = [
    {'name': 'sElwUYiLXGHaQCKbdxtnvVzqIehfFWkJcPSTurgNoRD', 'number': 8583},
    {'name': 'XJEtNsIFfcwHTMhqAvRkiygjbUGzZQPdS', 'number': 8127},
    {'name': 'ZIeAGosUKJbjOdylM', 'number': 5862},
    {'name': 'HYvcafoXkC', 'number': 7458},
    {'name': 'tATJCjNuizOlGckXBpyVqSQL', 'number': 530},
    {'name': 'TFYixotjhXzNZPvHnkraRDpAMEImJfqdcVGLC', 'number': 7052},
    {'name': 'JCEGfoKDHRrcIkPQSqiVgNshZOBaMdXjAlxwUzmeWLy', 'number': 6168},
    {'name': 'IpCTwUAQynSizJtcsuDmbX', 'number': 6492},
    {'name': 'fTrcoXSBJNFhAkzWpDMxsEiLmZRvgnC', 'number': 382},
    {'name': 'ulVNmqKTpPXfEIdiykhDjMrUGOYazLBFvgnWwsRtJoQbxSe', 'number': 2061}
]

Using following code, I'm creating the index and inserting the data:

from elasticsearch import Elasticsearch
from data import data  # the data I've shown above

INDEX = 'elasticie'
es = Elasticsearch('http://127.0.0.1:9200')

for _ in data:
    es.index(index=INDEX, body=_)

I'm trying to sort data based on number, asc or desc Here is what I tried so far:

es.search(index=INDEX, params={'sort': {'number': {'order': 'asc'}})
es.search(index=INDEX, params={'sort': {'number': 'asc'})
es.search(index=INDEX, params={'sort': [('number', 'asc')]})
es.search(index=INDEX, params={'sort': {'number': {'order': 'asc', 'ignore_unmapped': True}})
es.search(index=INDEX, params={'sort': {'number': {'order': 'asc', 'unmapped_type': 'integer'}})
es.search(index=INDEX, params={'sort': {'number': {'order': 'asc', 'unmapped_type': 'long'}})
es.search(index=INDEX, params={'sort': {'number.raw': 'asc'})

Not of the above methods worked for me, The result is the same as the inserted data, If I assign the above lines to a variable named search_result and print the result using the following code:

for index, result in enumerate(search_result['hits']['hits']):
    print(f'{index}. {result["_source"]["number"]}')

I'll get the following result:

0. 8583
1. 8127
2. 5862
3. 7458
4. 530
5. 7052
6. 6168
7. 6492
8. 382
9. 2061

Which is obviously not sorted using number field!!

I don't know what I'm doing wrong, I'm using ElasticSearch 7.6 and Python 3.8

How can I make the sorting results work?

Update

Based on debugging logs, Python is sending a GET request to the following URL using the first method: http://127.0.0.1:9200/elasticie/_search?sort={%27number%27%3A+{%27order%27%3A+%27asc%27}}


Solution

  • My mistake, I read the documentation and the code functionality using help and dir functions

    There is no parameter named sort defined on the Elasticsearch.search method, That's why I thought I should use it as a key within the params dict that it takes,

    Thanks to @OpsterElasticSearchNinja and his comment, I realized there is something wrong with either the library or how I'm using it

    Sending POST request with sort key as post body worked well, So I decided to read the whole source code and find out what's going wrong?

    @query_params(
        #...
        "size",
        "sort",
        #...
    )
    def search(self, body=None, index=None, doc_type=None, params=None):
        # ...
    

    This is how the sort parameter is defined, using a decorator on runtime!!

    That's when I tried this code, and somehow it worked!

    es.search(index=INDEX, sort=['number:asc'])