I'm trying to implement the following Elasticsearch query using django-elasticsearch-dsl and am having some difficulty
Query
{
"query":{
"nested":{
"path":"ip_addresses",
"query":{
"bool":{
"filter":[
{
"range":{
"ip_addresses.ip":{
"gte":"192.168.1.0",
"lte":"192.168.1.255"
}
}
}
]
}
}
}
}
}
Code
def search_ip_range(self, start: str, end: str):
range_query = Q('range', gte=start, lte=end)
search = Search()
search = search.query('nested', path='ip_addresses', query=range_query)
try:
response = search.execute()
pprint("Found {} results".format(response.hits.total.value))
for hit in response:
pprint(hit.detail_url)
except Exception as e:
pprint('Search error: {}'.format(e))
Error
RequestError(400, 'parsing_exception', '[range] query does not support [gte]')
As the author of elasticsearch-dsl-py
says, you'll need to use nested filters. One option would be:
...
range_query = Q('range', ip_addresses__ip={'gte': start, 'lte': end})
search = Search()
search = search.query('nested', path='ip_addresses', query=Q('bool', filter=[range_query]))
pprint(search.to_dict())
...
You can leave out the Q(bool, filter=
part but the range
won't then be wrapped in the it:
search = search.query('nested', path='ip_addresses', query=range_query)
Keep in mind that if you do wrap it in the filter
context, no scores will be calculated.