Elasticsearch: проверьте, существует ли GeoPoint в радиусе нескольких кругов - PullRequest
1 голос
/ 21 марта 2020

Мое требование - проверить, попадает ли полугулярная географическая точка в радиус круга или нет.
Я использую geoShape: circle для сохранения местоположения. Мой документ выглядит следующим образом:

PUT location_test/doc/1
    {
        "location" : {
            "type" : "circle",
            "coordinates" : [73.7769,18.5642],
          "radius": "10mi"
        }
    }

, а запрос выглядит следующим образом:

GET location_test/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "geo_shape": {
                "location": {
                  "shape": {
                    "type": "point",
                    "coordinates": [
                      73.877097,
                      18.455303
                    ],
                    "relation": "contains"
                  }
                }
              }
            }
          ]
        }
      }
    }

Этот запрос отлично работает для гео-формы с одним кругом.
Однако теперь я хочу проверить, конкретная географическая точка попадает в радиус нескольких окружностей.
Можем ли мы иметь наш документ что-то вроде:

{
  "location": [
    {
      "type": "circle",
      "coordinates": [
        73.7769,
        18.5642
      ],
      "radius": "10mi"
    },
    {
      "type": "circle",
      "coordinates": [
        -118.240853,
        34.052997
      ],
      "radius": "10mi"
    }
  ]
}

и иметь запрос, чтобы проверить, попадает ли географическая точка в какую окружность.
Или есть Есть ли другой способ добиться этого?

РЕДАКТИРОВАТЬ Является ли хорошей практикой использование массива географических точек для сортировки документов по определенной географической точке?

Mapping :
    {
      "mappings": {
        "doc": {
          "properties": {
            "locationPoint": {
              "type": "geo_point"
            }
          }
        }
      }
    }

PUT location_test2/doc/1
{
  "locationPoint": ["34.075433, -118.307228","36.336356,-119.304597"]
}

PUT location_test2/doc/2
{
  "locationPoint": ["34.075433, -118.307228"]  
  }

GET location_test2/_search
{
  "sort": [
      {
      "_geo_distance": {
        "locationPoint": "34.075433, -118.307228",
        "order": "asc"
      }
    }
  ]
}

1 Ответ

3 голосов
/ 21 марта 2020

Вы, безусловно, можете иметь несколько кружков в одном документе, и поиск все равно будет совпадать, если любой из кружков содержит вашу точку. Сокращение шагов для краткости:

PUT location_test
{"mappings":{"properties":{"location":{"type":"geo_shape","strategy":"recursive"}}}}

Принимая в ваш массив кругов:

PUT location_test/_doc/2
{"location":[{"type":"circle","coordinates":[73.7769,18.5642],"radius":"10mi"},{"type":"circle","coordinates":[-118.240853,34.052997],"radius":"10mi"}]}

Тот же запрос, что и для одного круга.

GET location_test/_search
{"query":{"bool":{"must":[{"geo_shape":{"location":{"shape":{"type":"point","coordinates":[73.7769,18.5642],"relation":"contains"}}}}]}}}

, что делает наш интерес c. Противоречивым, но приятным моментом является то, что не имеет значения , если вы предоставляете один объект или список объектов. ElasticSearch обрабатывает оба без изменения сопоставления.


Просто обратите внимание, что ваши круги находятся на противоположных сторонах земного шара:

enter image description here

Если вы знаете об этом и запрашиваете ваш locations, то все в порядке.


С точки зрения производительности, помните, что круги представлены как многоугольники enter image description here

, которые, в зависимости от вашей версии ES, представлены в виде набора треугольников .

Так что вы можете индексировать окружность -похоже на полигоны вместо кругов, чтобы, возможно, ускорить индексацию или даже подумать о слиянии ваших кругов в набор полигонов (MultiPolygon), потому что, как это выглядит, ваш список кругов представляет связанные геометрии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...