场景
现在基于地理位置的app层出不穷,支持地理位置的组件也有不少,Elasticsearch也不例外,并且ES可以把地理位置、全文搜索、结构化搜索和分析结合到一起,我们来看一下。
注意
本文章基于es7,用es6的话可能语法稍有不同,仅供参考
geo point数据类型
Elasticsearch基于地理位置的搜索,有一个专门的对象geo_point存储地理位置信息(经度,纬度),并且提供了一些基本的查询方法,如geo_bounding_box。
建立geo_point类型的mapping
PUT /my_geo
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
},
"name": {
"type": "text"
}
}
}
}
创建了一个my_geo索引,添加了一个字段location,它的类型是geo_point
。
插入数据
#latitude:维度,longitude:经度
POST /my_geo/_doc
{
"name":"路人甲",
"location":{
"lat": 39.90279998006104,
"lon": 116.42703999493406
}
}
POST /my_geo/_doc
{
"name":"路人乙",
"location":{
"lat": 39.93367367974064,
"lon": 116.47845257733152
}
}
范围查询(3种方式)
1.geo_distance查询,根据当前位置的距离进行搜索,非常实用
查询5km范围内都有谁,filter
使用geo_distance
查询,我们定义距离distance
为5km,再指定geo类型的字段location
POST /my_geo/_search
{
"query":{
"bool":{
"filter":{
"geo_distance":{
"distance":"5km",
"location":{
"lat":39.93031708627304,
"lon":116.4470385453491
}
}
}
}
}
}
结果发现:路人甲,路人乙都出来啦,你再试着改变举例3km看看效果呢?
2.geo_bounding_box查询,查询某个矩形的地理位置范围内的坐标点
POST /my_geo/_search
{
"query": {
"geo_bounding_box": {
"location": {
"top_left":{
"lon": 116,
"lat": 39.99
},
"bottom_right":{
"lon": 117,
"lat": 39.9
}
}
}
}
}
3.geo_polygon查询,查询三个点(三角形)范围内的坐标点
支持多边形,只是这个过滤器使用代价很大,尽量少用
POST /my_geo/_search
{
"query": {
"geo_polygon": {
"location": {
"points": [
{
"lon": 115,
"lat": 23
},
{
"lon": 113,
"lat": 25
},
{
"lon": 112,
"lat": 21
}
]
}
}
}
}
按距离排序
按从近到远排序
POST /my_geo/_search
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "5km",
"location": {
"lat": 39.93031708627304,
"lon": 116.4470385453491
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 39.93031708627304,
"lon": 116.4470385453491
},
"order": "asc",
"unit": "m",
"distance_type": "plane"
}
}
]
}
_geo_distance: 固定写法,下面为指定位置的经纬度
unit: 距离的单位,m/km都行
distance_type: 计算距离的方式,sloppy_arc (默认值), arc (精准的) and plane (最快速的)
返回值:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "my_geo",
"_type" : "_doc",
"_id" : "kH1qEHQBfUQLnDXv35Mt",
"_score" : null,
"_source" : {
"name" : "路人乙",
"location" : {
"lat" : 39.93367367974064,
"lon" : 116.47845257733152
}
},
"sort" : [
2704.400492813901
]
},
{
"_index" : "my_geo",
"_type" : "_doc",
"_id" : "j31qEHQBfUQLnDXvfJOK",
"_score" : null,
"_source" : {
"name" : "路人甲",
"location" : {
"lat" : 39.90279998006104,
"lon" : 116.42703999493406
}
},
"sort" : [
3503.0165324004943
]
}
]
}
}
sort里面的内容,就是与当前位置的地面距离,单位是m。
统计我当前位置几个范围内人的数量
unit表示距离单位,常用的是mi和km。
distance_type表示计算距离的方式,sloppy_arc (默认值), arc (精准的) and plane (最快速的)。
POST /my_geo/_search
{
"size": 0,
"aggs": {
"group_by_distance": {
"geo_distance": {
"field": "location",
"origin": {
"lon": 39.933673679,
"lat": 116.47845257
},
"unit": "mi",
"distance_type": "arc",
"ranges": [
{"from": 0,"to": 1000},
{"from": 1000,"to": 2000},
{"from": 2000,"to": 5000}
]
}
}
}
}
标签:distance,地理位置,my,lon,搜索,location,lat,elasticsearch,geo From: https://blog.51cto.com/u_6353447/5886789