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
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
stringfields, theTermRangeQuery, while for number/date fields, the query is aNumericRangeQuery.
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.