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
string
fields, 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.