ホテルなどの宿泊施設をGoogle Map 上にマーカーを表示することを考えたとき、 Google Mapの中心を動かすと同時に(または何かボタンを押して)その四隅の緯度経度内にはいる施設を再検索をしたい
これを実現するためにElasticsearchのGeo-bounding box query
を使用してみる
Geo-bounding box query
はESのドキュメント(施設)の位置情報を基にフィルタリングするためのクエリ
施設のドキュメントにはlatitude
とlongitude
がペアに保持されるgeo_point
typeのフィールドがある必要がある
Geo-point datatype | Elasticsearch Reference [7.x] | Elastic
PUT my_index { "mappings": { "properties": { "location": { "type": "geo_point" } } } } PUT my_index/_doc/1 { "text": "Geo-point as an object", "location": { "lat": 41.12, "lon": -71.34 } }
保持のしかたは他にも以下のようなやり方が可能
PUT my_index/_doc/2 { "text": "Geo-point as a string", "location": "41.12,-71.34" } PUT my_index/_doc/3 { "text": "Geo-point as a geohash", "location": "drm3btev3e86" } PUT my_index/_doc/4 { "text": "Geo-point as an array", "location": [ -71.34, 41.12 ] } PUT my_index/_doc/5 { "text": "Geo-point as a WKT POINT primitive", "location" : "POINT (-71.34 41.12)" }
このでフィールドに対して検索をかける
指定したエリアの範囲で検索する場合
エリアの左上
と右下
の緯度経度を使って以下のようなクエリをつくる
GET my_index/_search { "query": { "bool" : { "must" : { "match_all" : {} }, "filter" : { "geo_bounding_box" : { "location" : { "top_left": { "lat": 42, "lon": -72 }, "bottom_right": { "lat": 40, "lon": -74 } } } } } } }
指定した中心からの距離で検索かける場合
GET /my_locations/_search { "query": { "bool" : { "must" : { "match_all" : {} }, "filter" : { "geo_distance" : { "distance" : "200km", "location" : { "lat" : 40, "lon" : -70 } } } } } }
distanceのunitはこちら
https://www.elastic.co/guide/en/elasticsearch/reference/7.x/common-options.html#distance-units
指定した多角形の図形内で検索かける場合
GET /my_locations/_search { "query": { "bool" : { "must" : { "match_all" : {} }, "filter" : { "geo_polygon" : { "location" : { "points": [ [40, -70], [30, -80], [20, -90] ] } } } } } }