elasticsearch地理位置查询
elasticsearch地理位置查询
一、背景
最近有个需求,需要获取某个位置附近的楼盘,**比如:**获取当前用户所在位置,方圆100km千米之内的楼盘信息。经过调研,发现可以使用 redis
、mongodb
、elasticsearch
等实现。经过考虑之后决定使用es
来实现,此处简单记录下es
中geo
方面api的使用。
二、geo数据类型
在es
中存在2种地理位置数据类型,geo_point
和geo_shape
。es无法自动识别这种数据类型,需要在创建mapping的时候,自己手动指定。
1、geo_point
geo_point
使用的是经纬度
的坐标点,可以计算落在某个矩形内的点、以某个点为半径(圆)的点、某个多边形内的点(弃用了)、排序、聚合等操作。
2、geo_shape
geo_shape
表示的是一个复杂的图形,使用的是GeoJSON
的格式来表示复杂的图形。比如:我们要表示一个图书馆的坐标位置,如果图书馆占的位置比较大,用一个点表示可能就不准了,此时就可以使用geo_shape
来表示了。
不过这种数据类型也有缺点:比如不能排序等等(因为是多边形的点)。
三、此处对geo_point类型实战
1、背景
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、图中的短小的箭头️表示边界。
2、插入地点数据
1、创建索引
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"
}
}
}
}
注意️:
1、在索引中,我们自己指定来location
字段的类型为geo_point
类型。
2、building_name
的字段类型为keyword
表示不分词,这个字段只是为了测试,没有什么用。
3、不用指定索引的type,在es7中只有一个type。
2、插入地理位置数据
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":"POINT (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、从上面可知:地理位置的插入的格式可以存在4种
方式。
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]
5、 还有一种 geohash 的格式
需要注意的是:使用 数组/Well-Known-Text 的格式的时候,经纬度是反过来的。
3、执行检索
1、geo_bounding_box 矩形过滤
从上图可知左上角和右下方的坐标分别为 (121.444075,31.265395)和(121.468417,31.253845)
执行查询,应该可以查询出 上海站
和万业远景大厦
1、es查询语句
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
}
}
}
}
}
}
}
2、查询结果
从图中可以看到,查询出来了 上海站
和万业远景大厦
,结果是正确的。
2、geo_distance 圆形查询
这个是距离查询,是以某个点向周围扩算的距离范围。
在上一步的背景中,我们知道上海站
的坐标(121.462311,31.256224
),同时也知道了上海站距离各个周边的距离有多远,此处我们以上海站为中心,查询方圆600米
的建筑物,可知只有上海静安洲际酒店
和上海站
符合。
1、es查询语句
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
}
}
}
}
}
}
注意️:
1、distance_type
的值存在2个 arc
和plane
arc
:默认的方式,这种方式计算比较精确,但是比较慢,是把地球当作一个球体计算。plane
:这种方式计算比较快,但是可能不怎么准,越靠近赤道越准,是把地球当成平坦的进行计算。
2、distance
后面可用的单位有km
、m
、cm
、mm
、nmi
、mi
、yd
、ft
、in
2、查询结果
3、geo_distance 查询并排序,返回距离相隔多少米
1、es 查询语句
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"
}
}
]
}
注意️:
1、sort
执行排序。
2、查询结果
4、geo_distance聚合
需求:
1. 统计`上海站`500米之内的建筑物有多少。
2. 统计`上海站`500-1000米之内的建筑物有多少。
3. 统计`上海站`大于1000米的建筑物有多少。
1、es查询语句
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
}
}
}
}
2、查询结果
从上图中可以看到:
1、距离上海站在 0-500米之间的建筑物只有1个。
2、距离上海站在 500-1000之间的建筑物有1个。
3、距离上海站在 1000以上的有2个。
5、geo-polygon-多边形查询(过时)
在 es7.12 中已经过时了,推荐使用 geo_shape来实现
6、一个综合案例
1、需求:
1、查询语句query
,查询出所有的数据,并过滤出以上海站为中心的3km内的所有的建筑物。
2、aggs
,用于统计出上海在 500米以内、500-1000米、1000米之外的建筑物数量。
3、sort
用于排序。
4、post_filter
用于将结果缩小到上海站1000米以内。
2、查询结果
GET /geo_index/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
// 过滤出上海站周围3km范围内的建筑物
"filter": {
"geo_distance": {
"distance": "3km",
"distance_type": "arc",
"_name":"optional_name",
"location": {
"lat": 31.256224,
"lon": 121.462311
}
}
}
}
},
// 聚合上海站周围的建筑物的数量
"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
}
}
},
// 对查询到的结果排序,并将距离放到响应数据的 sort 字段中。
"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.256224,
"lon": 121.462311
},
"order": "desc",
"unit": "m",
"distance_type": "arc"
}
}
],
// 将结果缩小到上海站附近1km的范围内。
"post_filter": {
"geo_distance": {
"distance": "1km",
"location": {
"lat": 31.256224,
"lon": 121.462311
}
}
}
}
四、参考文档
2、距离单位
3、排序
4、矩形查询
6、坐标拾取系统
elasticsearch地理位置查询的更多相关文章
- Java High Level REST Client 使用地理位置查询
Java High Level REST Client 使用地理位置查询 一.需求 二.对应的query语句 三.对应java代码 1.引入 jar 包 2.创建 RestHighLevelClien ...
- 【转】elasticsearch的查询器query与过滤器filter的区别
很多刚学elasticsearch的人对于查询方面很是苦恼,说实话es的查询语法真心不简单- 当然你如果入门之后,会发现elasticsearch的rest api设计是多么有意思. 说正题,ela ...
- 基于百度地图SDK和Elasticsearch GEO查询的地理围栏分析系统(1)
本文描述了一个系统,功能是评价和抽象地理围栏(Geo-fencing),以及监控和分析核心地理围栏中业务的表现. 技术栈:Spring-JQuery-百度地图WEB SDK 存储:Hive-Elast ...
- Elasticsearch Kibana查询语法
Elasticsearch Kibana查询语法 2018年06月03日 23:52:30 wangpei1949 阅读数:3992 Elasticsearch Kibana Discover的搜 ...
- MongoDB的地理位置查询,以及和mysql的使用对比
MongoDB的一个特色就是具有丰富的查询接口,比如地理位置查询. 在地理位置查询上,MongoDB有着比传统关系型数据库的优势,下面举个例子. 当前移动互联网应用,按用户离目标门店距离排序上的场景很 ...
- ElasticSearch—分页查询
ElasticSearch查询—分页查询详解 Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回.那么,如何实现分页查询呢? 按照一般的查询流程来说,如 ...
- Elasticsearch 邻近查询示例
Elasticsearch 邻近查询示例(全切分分词) JAVA API方式: SpanNearQueryBuilder span = QueryBuilders.spanNearQuery(); s ...
- elasticsearch简单查询
elasticsearch简单查询示例: { "from": "0", //分页,从第一页开始 "size": "10" ...
- ElasticSearch高级查询
ElasticSearch高级查询 https://www.imooc.com/video/15759/0 ElasticSearch查询 1,子条件查询:特定字段查询所指特定值 1.1query c ...
随机推荐
- 异步处理方式之信号(一):基础知识和signal函数说明
文章目录 1. 引言 2. 信号的概念 2.1 信号操作之忽略信号 2.2 信号操作之捕捉信号 2.3 信号操作之执行系统默认操作 2.4 常见的信号 3. 函数signal 3.1 signal函数 ...
- Webpack:打包项目报错(eslint: debugger)
打包项目需要把项目中的debugger删除,否则会报错.
- Git 初识和使用
目录 目录 目录 概念 工作区/暂存区/版本库 master 版本号 常见命令 环境搭建 Linux 下 Git 和 GitHub 环境的搭建 Git 本地操作 本地仓库的创建和使用 查看信息 查看状 ...
- 洛谷P1803——凌乱的yyy(贪心)
题目描述 现在各大oj上有n个比赛,每个比赛的开始.结束的时间点是知道的. yyy认为,参加越多的比赛,noip就能考的越好(假的) 所以,他想知道他最多能参加几个比赛. 由于yyy是蒟蒻,如果要参加 ...
- 利用 Nginx 搭建小型的文件服务器
利用 Nginx 搭建小型的文件服务器 1.查看 Nginx 配置 android@localhost:/etc/nginx/conf.d$ nginx -hnginx version: nginx/ ...
- win10系统git的安装与使用命令
一.git简介 git是一个开源的分布式版本控制系统,可以高效的进行项目版本管理.分布式相比集中式最大的区别在于:分布式开发者可以提交到本地,每个开发者通过克隆在本地机器上拷贝一个完整的git仓库. ...
- Jenkins持续交付实战演练
jenkins web hook机制 运行jenkins任务触发方式: 主动运行 定时构建 就算代码库没有更新,也会构建. 通过代码库主动触发Jenkins的构建任务 jenkins向外暴露一个触发器 ...
- cas的基础配置
去除HTTPS的j基础认证方式 cas的:deployerConfigContext.xml <!-- Required for proxy ticket mechanism. -->&l ...
- 剑指offer计划27(栈与队列困难)---java
1.1.题目1 剑指 Offer 59 - I. 滑动窗口的最大值 1.2.解法 解题思路:(来自作者bigbeats) 相当于维护一个最大队列(队头元素最大,向队尾非严格递减) 在未形成窗口前,先构 ...
- Maven----将手动下载的jar包以命令行的方式安装到本地MavenRepository中
1.情景再现:准备实现SprintBoot的热部署功能,因没有对应jar时,在Eclipse中mvn install 会报错: 报错信息: [INFO] --- spring-boot-maven-p ...