在ElasticSearch中,地理位置通过geo_point这个数据类型来支持。地理位置的数据需要提供经纬度信息,当经纬度不合法时,ES会拒绝新增文档。这种类型的数据支持距离计算,范围查询等。在底层,索引使用Geohash实现。

1、创建索引

PUT创建一个索引cn_large_cities,mapping为city:

{"mappings": {"city": {"properties": {"city": {"type": "string"},"state": {"type": "string"},"location": {"type": "geo_point"}}}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

geo_point类型必须显示指定,ES无法从数据中推断。在ES中,位置数据可以通过对象,字符串,数组三种形式表示,分别如下:

# "lat,lon"
"location":"40.715,-74.011""location": {"lat":40.715,"lon":-74.011
}# [lon ,lat]
"location":[-74.011,40.715]
  • 1

POST下面4条测试数据:

{"city": "Beijing", "state": "BJ","location": {"lat": "39.91667", "lon": "116.41667"}}{"city": "Shanghai", "state": "SH","location": {"lat": "34.50000", "lon": "121.43333"}}{"city": "Xiamen", "state": "FJ","location": {"lat": "24.46667", "lon": "118.10000"}}{"city": "Fuzhou", "state": "FJ","location": {"lat": "26.08333", "lon": "119.30000"}}{"city": "Guangzhou", "state": "GD","location": {"lat": "23.16667", "lon": "113.23333"}}
  • 1

查看全部文档:

curl -X GET "http://localhost:9200/cn_large_cities/city/_search?pretty=true"
  • 1
  • 1

返回全部的5条数据,score均为1:

2、位置过滤

ES中有4中位置相关的过滤器,用于过滤位置信息:

  • geo_distance: 查找距离某个中心点距离在一定范围内的位置
  • geo_bounding_box: 查找某个长方形区域内的位置
  • geo_distance_range: 查找距离某个中心的距离在min和max之间的位置
  • geo_polygon: 查找位于多边形内的地点。

geo_distance

该类型过滤器查找的范围如下图:

下面是一个查询例子:

{"query":{"filtered":{"filter":{"geo_distance":"1km","location":{"lat":40.715,"lon": -73.988 }}}}
}
  • 1

以下查询,查找距厦门500公里以内的城市:

{"query":{"filtered":{"filter":{"geo_distance" : {"distance" : "500km","location" : { "lat" : 24.46667, "lon" : 118.10000 } }}}}
}
  • 16

geo_distance_range

{"query":{"filtered":{"filter":{"geo_distance_range":{"gte": "1km","lt":  "2km","location":{ "lat":40.715, "lon": -73.988 } }}}
}
  • 1
  • 6

geo_bounding_box

{"query":{"filtered":{"filter":{"geo_bounding_box":{"location":{ "top_left":{ "lat": 40.8, "lon":-74.0 }, "bottom_right":{ "lat":40.715, "lon": -73.0 } } }}}
}
  • 20

3、按距离排序

接着我们按照距离厦门远近查找:

{"sort" : [{"_geo_distance" : {"location" : {"lat" : 24.46667,"lon" : 118.10000}, "order" : "asc","unit" : "km"}}],"query": {"filtered" : {"query" : {"match_all" : {}}}}
}

结果如下,依次是厦门、福州、广州…。符合我们的常识:

{"took": 8,"timed_out": false,"_shards": {"total": 5,"successful": 5,"failed": 0},"hits": {"total": 5,"max_score": null,"hits": [{"_index": "us_large_cities","_type": "city","_id": "AVaiSGXXjL0tfmRppc_p","_score": null,"_source": {"city": "Xiamen","state": "FJ","location": {"lat": "24.46667","lon": "118.10000" }},"sort": [0]},{"_index": "us_large_cities","_type": "city","_id": "AVaiSSuNjL0tfmRppc_r","_score": null,"_source": {"city": "Fuzhou","state": "FJ","location": {"lat": "26.08333","lon": "119.30000" }},"sort": [216.61105485607183]},{"_index": "us_large_cities","_type": "city","_id": "AVaiSd02jL0tfmRppc_s","_score": null,"_source": {"city": "Guangzhou","state": "GD","location": {"lat": "23.16667","lon": "113.23333" }},"sort": [515.9964950041397]},{"_index": "us_large_cities","_type": "city","_id": "AVaiR7_5jL0tfmRppc_o","_score": null,"_source": {"city": "Shanghai","state": "SH","location": {"lat": "34.50000","lon": "121.43333" }},"sort": [1161.512141925948]},{"_index": "us_large_cities","_type": "city","_id": "AVaiRwLUjL0tfmRppc_n","_score": null,"_source": {"city": "Beijing","state": "BJ","location": {"lat": "39.91667","lon": "116.41667" }},"sort": [1725.4543712286697]}]}
}
  • 1

结果返回的sort字段是指公里数。加上限制条件,只返回最近的一个城市:

{"from":0,"size":1,"sort" : [{"_geo_distance" : {"location" : {"lat" : 24.46667,"lon" : 118.10000}, "order" : "asc","unit" : "km"}}],"query": {"filtered" : {"query" : {"match_all" : {}}}}
}

4、地理位置聚合

ES提供了3种位置聚合:

  • geo_distance: 根据到特定中心点的距离聚合
  • geohash_grid: 根据Geohash的单元格(cell)聚合
  • geo_bounds: 根据区域聚合

4.1 geo_distance聚合

下面这个查询根据距离厦门的距离来聚合,返回0-500,500-8000km的聚合:

{"query":{"filtered":{"filter":{"geo_distance" : {"distance" : "10000km","location" : { "lat" : 24.46667, "lon" : 118.10000 } }}}},"aggs":{"per_ring":{"geo_distance":{"field": "location","unit":  "km","origin":{"lat" : 24.46667,"lon" : 118.10000 },"ranges":[{"from": 0 , "to":500},{"from": 500 , "to":8000}]}}}}
  • 1

返回的聚合结果如下;

"aggregations": {"per_ring": {"buckets": [{"key": "*-500.0","from": 0,"from_as_string": "0.0","to": 500,"to_as_string": "500.0","doc_count": 2},{"key": "500.0-8000.0","from": 500,"from_as_string": "500.0","to": 8000,"to_as_string": "8000.0","doc_count": 3}]}}
  • 12

可以看到,距离厦门0-500km的城市有2个,500-8000km的有3个。

4.2 geohash_grid聚合

该聚合方式根据geo_point数据对应的geohash值所在的cell进行聚合,cell的划分精度通过precision属性来控制,精度是指cell划分的次数。

{"query":{"filtered":{"filter":{"geo_distance" : {"distance" : "10000km","location" : { "lat" : 24.46667, "lon" : 118.10000 } }}}},"aggs":{"grid_agg":{"geohash_grid":{"field": "location","precision":  2}}}}
  • 1

聚合结果如下:

"aggregations": {"grid_agg": {"buckets": [{"key": "ws","doc_count": 3},{"key": "wx","doc_count": 1},{"key": "ww","doc_count": 1}]}}
  • 1

可以看到,有3个城市的的geohash值为ws。将精度提高到5,聚合结果如下:

"aggregations": {"grid_agg": {"buckets": [{"key": "wx4g1","doc_count": 1},{"key": "wwnk7","doc_count": 1},{"key": "wssu6","doc_count": 1},{"key": "ws7gp","doc_count": 1},{"key": "ws0eb","doc_count": 1}]}}
  • 1
  • 16

4.3 geo_bounds聚合

这个聚合操作计算能够覆盖所有查询结果中geo_point的最小区域,返回的是覆盖所有位置的最小矩形:

{"query":{"filtered":{"filter":{"geo_distance" : {"distance" : "10000km","location" : { "lat" : 24.46667, "lon" : 118.10000 } }}}},"aggs":{"map-zoom":{"geo_bounds":{"field": "location"}}}}
  • 1
  • 15

结果如下:

 "aggregations": {"map-zoom": {"bounds": {"top_left": {"lat": 39.91666993126273,"lon": 113.2333298586309},"bottom_right": {"lat": 23.16666992381215,"lon": 121.43332997336984}}}}
  • 1
  • 6

也就是说,这两个点构成的矩形能够包含所有到厦门距离10000km的区域。我们把距离调整为500km,此时覆盖这些城市的矩形如下:

"aggregations": {"map-zoom": {"bounds": {"top_left": {"lat": 26.083329990506172,"lon": 118.0999999679625},"bottom_right": {"lat": 24.46666999720037,"lon": 119.29999999701977}}}}
  • 1
  • 2

5、参考资料

图解 MongoDB 地理位置索引的实现原理:http://blog.nosqlfan.com/html/1811.html
Geopoint数据类型:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html

ElasticSearch对地理数据查询(二)相关推荐

  1. Elasticsearch对地理数据查询(一)

    翻译版本:https://es.xiaoleilu.com/310_Geopoints/00_Intro.html 官方原文:https://www.elastic.co/guide/en/elast ...

  2. 数据库与elasticSearch,大数据查询性能PK

    每天早上七点三十,准时推送干货 一.介绍 在这篇文章中 利用springboot+elasticSearch,实现数据高效搜索,实战开发,我们介绍了 SpringBoot 整合 ElasticSear ...

  3. 数据库实验三 数据查询二

    第1关:多表查询 任务描述 本关任务:查询来自借阅.图书.读者数据表的数据 为了完成本关任务,你需要掌握: 如何多表查询 相关知识 查询多个数据表 在实际应用中,查询经常会涉及到几个数据表. 基于多个 ...

  4. 如何用你最熟悉的 SQL 来查询 Elasticsearch 中的数据?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! Elasticsearch 是一个全文搜索引擎,具有您期 ...

  5. CYQ.Data 轻量数据层之路 使用篇-MAction 数据查询 视频 D (二十一)

    2019独角兽企业重金招聘Python工程师标准>>> 说明: 本次录制主要为使用篇:CYQ.Data 轻量数据层之路 使用篇二曲 MAction 数据查询(十三)   的附加视频教 ...

  6. MySQL学习记录 (二) ----- SQL数据查询语句(DQL)

    相关文章: <MySQL学习记录 (一) ----- 有关数据库的基本概念和MySQL常用命令> <MySQL学习记录 (二) ----- SQL数据查询语句(DQL)> &l ...

  7. ElasticSearch倒排索引原理 数据的写入与查询过程

    Elasticsearch在生产中充当的角色 业务上,最早启用Elasticsearch(下称ES)是为了解决模糊查询的问题.具体业务场景为大量抓取回来的短视频内容.热门微博.公众号文章.小红书笔记. ...

  8. 数据库实验二之数据查询

    实验二 数据查询 一.实验目的 1.理解数据库中数据的其他查询方法和应用: 2.学会各种查询要求的实现: 3.学会各种查询的异同及相互之间的转换方法. 二. 实验内容 在实验1的基础上,练习其它查询语 ...

  9. 如何用 SQL 来查询 Elasticsearch 中的数据?

    大点击"开发者技术前线",选择"星标" 在看|星标|留言,  真爱 回复"666",获取一份技术人专属大礼包 参考:https://elas ...

最新文章

  1. Hive group by实现-就是word 统计
  2. 图片的批量下载 和 爬虫爬取图片数据集
  3. OpenWRT(基于LEDE17.01.4)Open***的Client与Server端内网互通
  4. sparkstreaming监听hdfs目录_flume kafka和sparkstreaming整合
  5. when is extension component's resource bundle loaded
  6. mysql行锁同索引键问题_mysql 锁问题 (相同索引键值或同一行或间隙锁的冲突)
  7. 案例:无人船测量点位数据+ArcGIS 10.6软件生成三维水下地形的两种方法
  8. boostrap 鼠标滚轮滑动图片_16种基于Bootstrap的css3图片hover效果
  9. python bootstrap 4_Python3.4+Django1.9+Bootstrap3
  10. java如何禁用usb_IT技巧分享59: 如何禁用USB端口以及光驱来保证数据不被泄露
  11. linux上docker安装centos7.2
  12. 控制QLineEdit的输入范围
  13. json串 转 list<class> 方法 List转JSONArray和JSONArray转List
  14. 游戏筑基开发之栈、队列及基本功能实现(使用C语言链表的相关知识)
  15. java list加入listview_将卡添加到ListView
  16. 1688-item_search_img - 按图搜索1688商品(拍立淘)
  17. colorbox加载ajax调用的html页面,ColorBox
  18. 3DEXPERIENCE ENOVIA
  19. php网上商城作业,商城主体作业
  20. Carson带你学数据结构:手把手带你了解 ”图“ 所有知识!(含DFS、BFS)

热门文章

  1. 对肺结节几何矩的特征提取
  2. 数据库原理与应用(SQL Server)笔记 第四章 嵌套查询和其他查询子句
  3. mysql 磁盘利用率100_磁盘空间使用率100%的故障处理
  4. MySQL之日期时间处理函数_MySQL之日期时间处理函数
  5. css 缩放_【开发小技巧】06—如何使用CSS在鼠标悬停时缩放图像?
  6. composer 完整路径才能访问_Win7系统IIS,无法访问ASP,提示错误 '80004005'
  7. linux安装python_VTK:华为笔记本电脑+深度deepin-linux+python下安装和入门
  8. 纸的大小图解_图解常见纸张开数尺寸印前小常识
  9. 鸿蒙1号六年级下册课时练答案,【奥数天天练】小学1~6年级思维能力特训|第310期...
  10. mysql大量重复值建立索引_对于有大量重复数据的表添加唯一索引