Range Query on String [Elastic Search] Range Query on String [Elastic Search] elasticsearch elasticsearch

Range Query on String [Elastic Search]


As you have already encountered, the drawback of not using a correct data type results in unexpected behaviour. I quiet didn't get why value can be either string of numeric etc. But considering the use-case I would suggest to define different field for different type of value. Considering the query that you are trying to match with, requires the relation between key and value field to be maintained. I therefore would suggest you to define a nested field instead of plain object field.

The reason for not using object field is that elastisearch flattens the object and then index it. Flattening the object result in loss of relationship between the properties. Read more on this here.

Now, consider the following example (elastic 7.x) :

Step 1: Define mapping with correct type for fields

PUT test{  "mappings": {    "properties": {      "nestedField": {        "type": "nested",        "properties": {          "key": {            "type": "keyword"          },          "stringValue": {            "type": "text",            "fields": {              "keyword": {                "type": "keyword"              }            }          },          "numericValue": {            "type": "integer"          }        }      }    }  }}

We created a nestedField with fields key, stringValue, numericValue of type keyword (not analysed), text (default standard analyser and sub field of type keyword if exact match is required), integer respectively.

Step 2: Index document

PUT test/_doc/1{  "nestedField": [    {      "key": "foo",      "stringValue": "lisa"    },    {      "key": "bar",      "numericValue": 19    }  ]}PUT test/_doc/2{  "nestedField": [    {      "key": "foo",      "stringValue": "mary"    },    {      "key": "bar",      "numericValue": 9    }  ]}

Note how I indexed string value and numeric value.

Step 3: Query as required.

To query on nested type field you have to use nested query.

GET test/_search{  "query": {    "nested": {      "path": "nestedField",      "query": {        "bool": {          "filter": [            {              "term": {                "nestedField.key": "bar"              }            },            {              "range": {                "nestedField.numericValue": {                  "gt": 10                }              }            }          ]        }      }    }  }}

The above query will return only doc 1 because for doc 2 even though key: bar is present but the related value (numericValue) is not greater than 10.


From the many Stack-overflow/ Github and other resources it confirms that this feature is not available for text.

The only way to use it is via having corresponding numeric field while indexing:

[ { "key" : "foo", "value" : "lisa" },  { "key" : "bar", "value" : "19", "numericValue" : 19}] 

and index on the basis of numeric value as well. Later use this while fetching from ES.

1. match key as "bar"2. range { "numericValue" : {gt:10}}