Search code examples
elasticsearchelasticsearch-6elasticsearch-nested

Elasticsearch Range Query on Nested Keyword field


I'm trying to run a range query on a nested keyword field in Elasticsearch 6.4, but I'm not having any luck:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "metas",
            "query": {
              "bool": {
                "must": [
                  { "term": { "metas.key": "duration"} },
                  { "range": {"metas.value": {"gte": "100", "lte": "200"} } }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

So I'm looking for all documents where metas.key is duration and metas.value is between 100-200 (formatted as string). My query is successful, but includes any metas.value regardless of it's value, I'm e.g. getting documents where the value is 20 etc. My mapping (in Ruby) looks like this:

indexes :metas, type: :nested do
  indexes :key, type: :keyword
  indexes :value, type: :keyword
  indexes :created_at, type: :date
  indexes :updated_at, type: :date
end

Solution

  • As Nishant mentioned in the comment, you need to change the type to a numeric datatype.

    The Range Query documentation states:

    Matches documents with fields that have terms within a certain range. The type of the Lucene query depends on the field type, for string fields, the TermRangeQuery, while for number/date fields, the query is a NumericRangeQuery.

    So when you have a keyword (which is a string type) Elasticsearch is using TermRangeQuery for comparison and there the alphabetical order is taken. Alphabetically the 20 is between 100 and 200.