Запрос геодезического расстояния ElasticSearch
-
21-12-2019 - |
Вопрос
Я использую запрос geodistance в python следующим образом
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": "20miles",
"location": {
"lat": 51.512497,
"lon": -0.052098
}
}
}
}
}
}
Он работает корректно.Моя проблема заключается в том, как присвоить "расстоянию" значение из документа.У меня есть такое поле, как это distance: 50
в моем индексе для каждой записи, и я хочу использовать его как значение расстояния в geodistance.Я пытался "distance":doc['distance'].value
но это не работает.
Решение
Обычные запросы и фильтры не ожидают, что в них будут помещены скрипты.
Предполагая, что вы сохранили geo_point
с именем поля location
, тогда вы хотите использовать фильтр скриптов используя doc['field_name'].Расстояние в милях (широта, lon) (в отличие от distance(lat, lon)
потому что стандартными единицами измерения являются meters
по состоянию на v1.0.0
):
{
"filtered" : {
"query" : { "match_all" : { } },
"filter" : {
"script" : {
"script" :
"doc['location'].distanceInMiles(lat, lon) < doc['distance'].value",
"params" : {
"lat" : 51.512497,
"lon" : -0.052098
}
}
}
}
}
Если вы запускаете экземпляр Elasticsearch, где он использует ранее стандартные единицы измерения miles
(до-v1.0.0
), затем вы можете использовать обычный distance
функции (или если ваши устройства для distance
уже оказалось, что это соответствует нынешнему стандарту meters
по состоянию на v1.0.0
):
{
"filtered" : {
"query" : { "match_all" : { } },
"filter" : {
"script" : {
"script" :
"doc['location'].distance(lat, lon) < doc['distance'].value",
"params" : {
"lat" : 51.512497,
"lon" : -0.052098
}
}
}
}
}
Примечание:вы могли бы указать значения lat
и lon
непосредственно внутри скрипта для одноразового выполнения, но скрипты компилируются и кэшируется, поэтому использование параметров позволяет повторно использовать их и, следовательно, ускорить выполнение после первого использования.
Как отмечено в документации, вы можете кэшировать результат фильтра, добавив "_cache" : true
к фильтру, но результатом работы фильтра является нет кэшируется по умолчанию.