Geo-point地理位置
在es中存在2种地理位置数据类型,geo_point和geo_shape。es无法自动识别这种数据类型,需要在创建mapping的时候,自己手动指定。
geo_point使用的是经纬度的坐标点,可以计算落在某个矩形内的点、以某个点为半径(圆)的点、排序、聚合等操作。
geo_shape表示是一个复杂的图形,使用的是GeoJSON的格式来表示复杂的图形。比如:要表示一个图书馆的坐标位置,如果图书馆占的位置比较大,用一个点表示可能就不准了,就可以使用geo_shape来表示
使用场景

1、图中的 ① ② ③ ④ 表示是需要加入到 es 中的建筑物
| 地点 | 坐标 | 距离地点 | 相隔距离 | 备注 |
| 上海站 | 121.462311,31.256224 | 上海站 | ||
| 上海静安洲际酒店 | 121.460186,31.251281 | 上海站 | 586.24米 | 上海站和该酒店大概像个586.24米 |
| 交通公园 | 121.473939,31.253531 | 上海站 | 1146.45米 | |
| 万业远景大厦 | 121.448215,31.26229 | 上海站 | 1501.74米 |
2、图中的圆形、正方形、多边形表示后期需要使用 es 查询出来里面里面的地点。
3、图中的短小的箭头➡️表示边界。
创建索引
PUT /geo_index { "settings": { "number_of_shards": 2, "number_of_replicas": 2, "analysis": { "analyzer": { "default": { "type": "ik_max_word" } } } }, "mappings": { "properties": { "building_name": { "type": "keyword" }, "location": { "type": "geo_point" } } } }
插入地理位置
POST _bulk {"create":{"_index":"geo_index","_id":1}} {"building_name":"上海站","location":{"lat":31.256224,"lon":121.462311}} {"create":{"_index":"geo_index","_id":2}} {"building_name":"上海静安洲际酒店","location":[121.460186,31.251281]} {"create":{"_index":"geo_index","_id":3}} {"building_name":"交通公园","location":"31.253531,121.473939"} {"create":{"_index":"geo_index","_id":4}} {"building_name":"万业远景大厦","location":[121.448215,31.26229]}
地理位置的插入的格式
1、 {"lat":"","lon":""}
2、 "lat,lon"
3、 [Well-Known Text](https://docs.opengeospatial.org/is/12-063r5/12-063r5.html) "POINT (lon lat)"
4、 [lon,lat]
1、geo_bounding_box 矩形过滤

从上图可知左上角和右下方的坐标分别为 (121.444075,31.265395)和(121.468417,31.253845),执行查询,应该可以查询出 上海站和万业远景大厦
GET /geo_index/_search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "geo_bounding_box": { "location": { "top_left": { "lat": 31.265395, "lon": 121.444075 }, "bottom_right": { "lat": 31.253845, "lon": 121.468417 } } } } } } }
geo_distance 圆形查询
距离查询,是以某个点向周围扩算的距离范围
上海站的坐标(121.462311,31.256224),同时也知道了上海站距离各个周边的距离有多远,此处我们以上海站为中心,查询方圆600米的建筑物,可知只有上海静安洲际酒店和上海站符合。
GET /geo_index/_search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "geo_distance": { "distance": "600m", "distance_type": "arc", "_name":"optional_name", "location": { "lat": 31.256224, "lon": 121.462311 } } } } } }
distance_type的值存在2个 arc和plane
-
arc:默认的方式,这种方式计算比较精确,但是比较慢,是把地球当作一个球体计算。 -
plane:这种方式计算比较快,但是可能不怎么准,越靠近赤道越准,是把地球当成平坦的进行计算。
distance后面可用的单位有km、m、cm、mm、nmi、mi、yd、ft、in
3、geo_distance 查询并排序,返回距离相隔多少米
GET /geo_index/_search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "geo_distance": { "distance": "600m", "distance_type": "arc", "_name": "optional_name", "location": { "lat": 31.256224, "lon": 121.462311 } } } } }, "sort": [ { "_geo_distance": { "location": { "lat": 31.256224, "lon": 121.462311 }, "order": "desc", "unit": "m", "distance_type": "arc" } } ] }
geo_distance聚合
1. 统计`上海站`500米之内的建筑物有多少。 2. 统计`上海站`500-1000米之内的建筑物有多少。 3. 统计`上海站`大于1000米的建筑物有多少。
GET /geo_index/_search { "query": { "bool": { "must": { "match_all": {} } } }, "aggs": { "rings_around_amsterdam": { "geo_distance": { "field": "location", "origin": { "lat": 31.256224, "lon": 121.462311 }, "unit": "m", "distance_type": "arc", "ranges": [ {"to": 500,"key": "first"}, {"from": 500,"to": 1000,"key": "second" }, {"from": 1000,"key": "third"} ], "keyed": true } } } }
https://juejin.cn/post/6953547277172473892
浙公网安备 33010602011771号