145

Elasticsearch throws a SearchParseException while parsing query if there are some documents found not containing field used in sort criteria.

SearchParseException: Parse Failure [No mapping found for [price] in order to sort on]

How can I successfully search these documents, even if some are missing the price field?

Tristan
  • 8,733
  • 7
  • 48
  • 96
Yadu
  • 4,891
  • 5
  • 19
  • 12
  • 1
    Your question/answer solved my problem - thank you. I edited to generalize it somewhat, feel free to rollback if that doesn't suit you. – Paul Bellora Jul 24 '13 at 20:26
  • 1
    Reference for handling this issue [Elasticsearch Link](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html) – Ajeesh May 09 '17 at 13:46

9 Answers9

134

After digging more, I found the solution as given below. ignore_unmapped should be explicitly set to true in the sort clause.

"sort" : [
       { "rating": {"order" : "desc" , "ignore_unmapped" : true} },
       { "price": {"order" : "asc" , "missing" : "_last" , "ignore_unmapped" : true} }
]

For further information have a look at the Elasticsearch references for:

Scotty.NET
  • 12,533
  • 4
  • 42
  • 51
Yadu
  • 4,891
  • 5
  • 19
  • 12
  • Hi, I have the same problem and I don't understand how this works... The attributes missing and ignore_unmapped should work together right ? If for example I set missing to "_last" and ignore_unmapped to "false", I still have the problem but I want the documents to be in the results in all cases even if they don't have the attribute. – c4k Oct 27 '13 at 15:47
  • I have this problem and "ignore_unmapped" don't work if your _type is empty (i.e. without any document indexed). – reinaldoluckman May 27 '15 at 15:37
  • 12
    Looks like the new strategy is to use [unmapped_type](https://www.elastic.co/guide/en/elasticsearch/reference/1.x/search-request-sort.html#_ignoring_unmapped_fields) – lukmdo May 29 '15 at 18:56
  • 3
    My queries always worked until today without updating any libraries etc. but today I started getting this same error. I now added `"ignore_unmapped" : true` and it started to work again but strange thing is, what has happened behind the scene! Who knows! Anyway, it works now. +1 – BentCoder May 19 '16 at 20:56
  • 2
    Can someone clarify the difference between "missing" and "unmapped"? For a certain field, if some documents have it while others don't, is such field treated as "missing" or "unmapped"? Does "missing" mean the field is in the document but the corresponding value is null? – Sher10ck May 17 '18 at 21:20
  • For making the NEST 6.x change, please follow this link https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/sort-usage.html – dotnetdev_2009 Jan 16 '19 at 15:28
61

For those looking for an example of both ignore_unmapped and unmapped_type please see my response here.

Note that "ignore_unmapped" is now deprecated in favor of "unmapped_type". This was done as part of #7039

From documentation: Before 1.4.0 there was the ignore_unmapped boolean parameter, which was not enough information to decide on the sort values to emit, and didn’t work for cross-index search. It is still supported but users are encouraged to migrate to the new unmapped_type instead.

By default, the search request will fail if there is no mapping associated with a field. The unmapped_type option allows to ignore fields that have no mapping and not sort by them. The value of this parameter is used to determine what sort values to emit. Here is an example of how it can be used:

{
    "sort" : [
        { "price" : {"unmapped_type" : "long"} },
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

If any of the indices that are queried doesn’t have a mapping for price then Elasticsearch will handle it as if there was a mapping of type long, with all documents in this index having no value for this field.

Community
  • 1
  • 1
Navneet Kumar
  • 909
  • 7
  • 6
5

if you are using es 6.7

try this one

sort : ["title.keyword:desc"]
Khalid Skiod
  • 103
  • 3
  • 8
4

Apparently ElasticSearch won't sort on null values. I was assuming it would treat null as being at the start or end (as with SQL ordering) but I believe it also triggers this error.

So if you see this error, you may need to ensure the sort attribute has a default value when it's sent to ElasticSearch.

I had this error with Rails+ElasticSearch+Tire because the sort column didn't have a default value, so was being sent to ES as null.

This issue indicates null values are handling, but it wasn't my experience. It's something worth trying anyway.

mahemoff
  • 44,526
  • 36
  • 160
  • 222
3

Let me try to help in the case that the original answer doesn't work for you. For ES 6.x try the code below, ignore_unmapped is deprecated.

"sort" : [
       { "rating": {"order" : "desc" , "unmapped_type" : "long"} },
       { "price": {"order" : "asc" , "missing" : "_last" , "unmapped_type" : "long"} }
]

More about sorting you can find on:

https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-sort.html

Ivan Marjanovic
  • 979
  • 1
  • 9
  • 15
2

I experienced the same problem (sorta; would get some errors, but some results), but in my case my search was being issued at the root (no index specified), and the errors I was getting were because the search/order was also looking to a Kibana index.

Stupid error, but maybe this'll help someone else who ends up here.

James Boutcher
  • 2,593
  • 1
  • 25
  • 37
  • i have the same issue .. but when i specify ignore unmapped i dont get any sorting at all when searching the root... this limits the ability to search for me if i have to define the index ... i would simply want all matching results to be sorted by a field if it exists, and fill use a default for those that dont.. EDIT: – mgoetzke Jan 29 '14 at 16:56
2

Elasticsearch 6.4

simply specify the index and that's it in Kibana

BEFORE

GET /_search
{
 
  "query": {
    "exists": {
      "field": "document_id"
    }
  },
  "sort": [
    {
      "document_id": { "order": "asc"  },
      "created_at":  { "order": "desc" }
    }
  ]
}

AFTER

GET /document-index/contact/_search  (here)
{

  "query": {
    "exists": {
      "field": "document_id"
    }
  },
  "sort": [
    {
      "document_id": { "order": "asc"  },
      "created_at":  { "order": "desc" }
    }
  ]
}
Brian Sanchez
  • 832
  • 1
  • 13
  • 11
0

You could also use script which gives you some flexibility:

"sort" : {
    "_script" : {
        "type" : "number",
        "script" : {
            "lang": "painless",
            "source": "return !doc['price'].empty ? doc['price'].value : 0"
        },
        "order" : "desc"
    }
}
Rafal Enden
  • 3,028
  • 1
  • 21
  • 16
0

When we use below code, where added_on is date, what happens !! attribute text is analyzed, meaning it is broken up into distinct words when stored, and allows for free-text searches on one or more words in the field

so there is "text" and "keyword" associated with fields, so if we need to use aggregation in the query, we need the field value in general the keyword.

BEFORE

"_source":{....}
"query" : {...}
"sort": [
{
  "added_on": {
    "order": "desc"
  }
}
]

AFTER
"_source":{....}
"query" : {...}
"sort": [
{
  "added_on.keyword": {
    "order": "desc"
  }
}
]
Abhishek Raj
  • 478
  • 7
  • 17