Elasticsearch实战——地理位置查询
文章目录
为了方便学习ES的地理位置查询,这里准备了一些地理坐标为测试数据,每一条数据都包含城市名称和地理坐标两个字段。首先把下面的内容保存到
geo.json
文件中:
{"index":{"_index":"geo","_id":"1"}}
{"city":"北京","localtion":"40.019559,116.312282"}
{"index":{"_index":"geo","_id":"2"}}
{"city":"乌鲁木齐","localtion":"43.863737,87.53891"}
{"index":{"_index":"geo","_id":"3"}}
{"city":"西安","localtion":"34.43376,108.879774"}
{"index":{"_index":"geo","_id":"4"}}
{"city":"郑州","localtion":"34.76845,113.589482"}
{"index":{"_index":"geo","_id":"5"}}
{"city":"杭州","localtion":"30.345351,120.102125"}
{"index":{"_index":"geo","_id":"6"}}
{"city":"济南","localtion":"36.688506,117.158558"}
{"index":{"_index":"geo","_id":"7"}}
{"city":"上海","localtion":"31.298035,121.426731"}
{"index":{"_index":"geo","_id":"8"}}
{"city":"武汉","localtion":"30.632158,114.28858"}
{"index":{"_index":"geo","_id":"9"}}
{"city":"广州","localtion":"23.150725,113.221536"}
然后创建一个索引:
PUT geo
{
"settings": {
"number_of_shards": "1",
"number_of_replicas": "0"
},
"mappings": {
"properties": {
"city": {
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
}
}
再执行:
$curl -X POST "localhost:9200/_bulk?pretty" -H 'Content-Type: application/json' --data-binary @geo.json
1. 半径查询(geo_distance query)
geo_distance
query可以查找在一个中心点指定半径范围内的地理文档。例如查询距离天津500km
以内的城市,搜索结果会返回北京、济南
,命令如下:
{
"query":{
"bool":{
"must":{
"match_all":{}
},
"filter":{
"geo_distance":{
"distance":"500km",
"location":{
"lat":"38.993443",
"lon":"117.158558"
}
}
}
}
}
}
按距离天津的距离排序:
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": "500km",
"location": {
"lat": "38.993443",
"lon": "117.158558"
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": "38.993443",
"lon": "117.158558"
},
"unit": "km"
}
}
]
}
2. 指定矩形内的查询(geo_bounding_box query)
geo_bounding_box
query用于查询落入指定的矩形内的地理坐标。查询中由两个点确定一个矩形,如图中的银川和南昌,在这两个点上分别做垂线(经度)和平行线(维度),相交线会组成一个矩形区域,可以查询到西安、郑州、武汉。
左上角和右下角查询
{
"query":{
"bool":{
"must":{
"match_all":{}
},
"filter":{
"geo_bounding_box":{
"location":{
"top_left":{
"lat":"38.532499",
"lon":"106.193769"
},
"bottom_right":{
"lat":"28.671728",
"lon":"115.907542"
}
}
}
}
}
}
}
左下角和右上角查询
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_bounding_box": {
"location": {
"top_right": {
"lat": "40.807062",
"lon": "119.108671"
},
"bottom_left": {
"lat": "22.12604",
"lon": "101.741623"
}
}
}
}
}
}
}
3. 查询指定多边形内的数据(geo_polygon query)
geo_polygon
query用于查找指定多边形内的地理点。例如,呼和浩特、重庆、上海三地组成的三角形,查询位置在改三角形区域内的城市。
{
"query":{
"bool":{
"must":{
"match_all":{}
},
"filter":{
"geo_polygon":{
"location":{
"points":[
{"lat":"40.835015","lon":"111.712958"},
{"lat":"29.640695","lon":"106.561715"},
{"lat":"31.23482","lon":"121.50032"}
]
}
}
}
}
}
}
4 查询geo_shape类型的数据(geo_shape query)
geo_shape
query用于查询geo_shape
类型的地理数据,地理形状之间包含的关系有:相交、包含、不相交三种。创建一个新的索引用于测试,其中location
字段的类型设置为geo_shape
类型:
PUT geoshape
{
"settings": {
"number_of_shards": "1",
"number_of_replicas": "0"
},
"mappings": {
"properties": {
"city": {
"type": "keyword"
},
"location": {
"type": "geo_shape"
}
}
}
}
geo_point
类型的字段是:纬度在前,经度在后,但是geo_shape
类型中的点是:经度在前,纬度在后。这点需要特别注意。
POST geoshape/_doc/1
{
"city":"西安-郑州",
"location":{
"type":"linestring",
"coordinates":[
[108.953364,34.372762],
[113.626277,34.76845]
]
}
}
查询包含在由银川和南昌组成的矩形的地理形状内的数据,由于西安和郑州组成的直线落在该矩形区域内,因此可以被查询到。
{
"query":{
"bool":{
"must":{
"match_all":{}
},
"filter":{
"geo_shape":{
"location":{
"shape":{
"type":"envelope",
"coordinates":[
[106.230564,38.50359],
[115.870747,28.704175]
]
},
"relation":"within"
}
}
}
}
}
}
5. 关注我
搜索微信公众号:java架构强者之路