地理坐标点是指地球表面可以用经纬度描述的一个点。地理坐标点可以用来计算两个坐标间的距离,还可以判断一个坐标是否在一个区域中,或在聚合中。
地理坐标点 需要显式声明对应字段类型为 geo-point
,字段被声明为 geo_point
类型 后,我们就可以索引包含经纬度信息的文档了。经纬度信息的形式可以是字符串、数组或者对象。
PUT /map
{
"mappings": {
"doc": {
"properties": {
"name":{
"type": "text"
},
"location": {
"type": "geo_point"
}
}
}
},
"settings": {
"number_of_shards": "3",
"number_of_replicas": "0"
}
}
PUT /map/doc/1
{
"name": "xiaoming",
"location": "40.715, -74.011"
}
PUT /map/doc/2
{
"name": "xiaohong",
"location": {
"lat": 40.722,
"lon": -73.989
}
}
PUT /map/doc/3
{
"name": "Pizza shop",
"location": [ -73.983, 40.719 ]
}
地理坐标点用字符串形式表示时是纬度在前,经度在后( "latitude,longitude" ),而数组形式表示时是经度在前,纬度在后( [longitude,latitude] )—顺序刚好相反。
四种地理坐标点相关的过滤器
geo_bounding_box
地理坐标盒模型过滤器
找出落在指定矩形框中的点。
geo_distance
地理距离过滤器
找出与指定位置在给定距离内的点。
geo_distance_range
地理距离区间过滤器(已经没有了,可以用geodistance-aggregation实现)
以给定位置为中心,找出落在大于最小距离且小于最大距离的环形区域的点
geo_polygon
找出落在多边形中的点。 这个过滤器使用代价很大 。当你觉得自己需要使用它,最好先看看 geo-shapes
类型
地理坐标盒模型过滤器geo_bounding_box
这是目前为止最有效的地理坐标过滤器了,因为它计算起来非常简单。你指定一个矩形的 顶部
, 底部
, 左边界
,和 右边界
,然后过滤器只需判断坐标的经度是否在左右边界之间,纬度是否在上下边界之间:
GET /map/doc/_search
{
"query": {
"bool": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 40.8,
"lon": -74.0
},
"bottom_right": {
"lat": 40.7,
"lon": -73.0
}
}
}
}
}
}
}
地理距离过滤器geo_distance
地理距离过滤器geo_distance
以给定位置为圆心画一个圆,来找出那些地理坐标落在其中的文档:
GET /map/doc/_search
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "1km",
"location": {
"lat": 40.715,
"lon": -73.988
}
}
}
}
}
}
找出所有与指定点距离在 1km 内的 location 字段。
中心点可以表示为字符串,数组或者对象。
地理距离过滤器计算代价昂贵。Elasticsearch 先画一个矩形框来围住整个圆形,这样就可以先用消耗较少的盒模型计算方式来排除掉尽可能多的文档。 然后只对落在盒模型内的这部分点用地理距离计算方式处理。
两点间的距离计算:
arc
最慢但最精确的是 arc
计算方式,这种方式把世界当作球体来处理。
plane
plane
计算方式把地球当成是平坦的,这种方式快一些但是精度略逊。在赤道附近的位置精度最好,而靠近两极则变差。
sloppy_arc
如此命名,是因为它使用了 Lucene 的 SloppyMath
类。这是一种用精度换取速度的计算方式,它使用 [Haversine formula]来计算距离。它比 arc
计算方式快 4 到 5 倍,并且距离精度达 99.9%。这也是默认的计算方式。
es默认使用sloppy_arc
计算距离,我们也可以指定计算方式
GET /map/doc/_search
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "1km",
"distance_type": "plane",
"location": {
"lat": 40.715,
"lon": -73.988
}
}
}
}
}
}
按距离排序
将搜索结果按距离排序
GET /map/doc/_search
{
"query": {
"bool": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 40.8,
"lon": -74.0
},
"bottom_right": {
"lat": 40.7,
"lon": -73.0
}
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 40.715,
"lon": -73.998
},
"order": "asc",
"unit": "km",
"distance_type": "plane"
}
}
]
}
unit是距离单位用于返回结果中表示距离的单位
网友评论