21

I'm having problem with an elasticsearch query. I want to be able to sort the results but elasticsearch is ignoring the sort tag. Here my query:

{
    "sort": [{
        "title": {"order": "desc"}
    }],
    "query":{
        "term": { "title": "pagos" }
    }
}

However, when I remove the query part and I send only the sort tag, it works. Can anyone point me out the correct way?

I also tried with the following query, which is the complete query that I have:

{
  "sort": [{
    "title": {"order": "asc"}
  }],
  "query":{
    "bool":{
      "should":[
        {
          "match":{
            "title":{
              "query":"Pagos",
              "boost":9
            }
          }
        },
        {
          "match":{
            "description":{
              "query":"Pagos",
              "boost":5
            }
          }
        },
        {
          "match":{
            "keywords":{
              "query":"Pagos",
              "boost":3
            }
          }
        },
        {
          "match":{
            "owner":{
              "query":"Pagos",
              "boost":2
            }
          }
        }
      ]
    }
  }
}

Settings

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 15,
          "token_chars": [
            "letter",
            "digit",
            "punctuation",
            "symbol"
          ]
        }
      },
      "analyzer": {
        "default" : {
          "tokenizer" : "standard",
          "filter" : ["standard", "lowercase", "asciifolding"]
        },
        "autocomplete": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding",
            "autocomplete_filter"
          ]
        }
      }
    }
  }
}

Mappings

{
  "objects": {
    "properties": {
      "id":             { "type": "string", "index": "not_analyzed" },
      "type":           { "type": "string" },
      "title":          { "type": "string", "boost": 9, "analyzer": "autocomplete", "search_analyzer": "standard" },
      "owner":          { "type": "string", "boost": 2 },
      "description":    { "type": "string", "boost": 4 },
      "keywords":       { "type": "string", "boost": 1 }
    }
  }
}

Thanks in advance!

  • What results are you getting and what do you expect? Also please show how you are sending your query (curl, Java, Python, Sense, etc)? – Val Dec 28 '15 at 12:57
  • Thanks, I'm using python (http://elasticsearch-dsl.readthedocs.org/en/latest/). The problem is that elasticsearch always returns the same results. The query part works fine, however returns the same list for asc and desc orders. – Alberto Menendez Romero Dec 28 '15 at 13:06
  • Can you show the python code you're using? – Val Dec 28 '15 at 13:14
  • Your code looks fine and should sort as expected. Can you add some example documents and the order in which you expect the results to be returned by Elasticsearch? Note that when you are sorting results, boosting queries is irrelevant. – bittusarkar Dec 28 '15 at 14:29
  • Possible duplicate of [How to sort on analyzed/tokenized field in Elasticsearch?](http://stackoverflow.com/questions/23273329/how-to-sort-on-analyzed-tokenized-field-in-elasticsearch) – Vinu Dominic Dec 29 '15 at 14:24

1 Answers1

26

The field "title" in your document is an analyzed string field, which is also a multivalued field, which means elasticsearch will split the contents of the field into tokens and stores it separately in the index. You probably want to sort the "title" field alphabetically on the first term, then on the second term, and so forth, but elasticsearch doesn’t have this information at its disposal at sort time.

Hence you can change your mapping of the "title" field from:

{
  "title": {
    "type": "string", "boost": 9, "analyzer": "autocomplete", "search_analyzer": "standard"
  }
}

into a multifield mapping like this:

{
  "title": {
    "type": "string", "boost": 9, "analyzer": "autocomplete", "search_analyzer":"standard",
    "fields": {
      "raw": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}

Now execute your search based on analyzed "title" field and sort based on the not_analyzed "title.raw" field

{
    "sort": [{
        "title.raw": {"order": "desc"}
    }],
    "query":{
        "term": { "title": "pagos" }
    }
}

It is beautifully explained here: String Sorting and Multifields

Tanveer Alam
  • 5,185
  • 4
  • 22
  • 43
Vinu Dominic
  • 1,040
  • 1
  • 16
  • 25
  • Thanks. That's exactly the problem. Now is working as it should. You saved my day!. – Alberto Menendez Romero Dec 28 '15 at 15:06
  • From ES v. 5 there is type "text" instead of a "string" (used in accepted answer). https://stackoverflow.com/questions/47452770/no-handler-for-type-string-declared-on-field-name – Ales Dec 13 '21 at 09:53