❤️ 博客主页:水滴技术
🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬
🌸 订阅专栏:大数据核心技术从入门到精通
文章目录
- 一、地理数据类型
- 1.1、geo_point 地理点类型
- 1.1.1、创建一个含有 geo_point 字段的索引
- 1.1.2、通过“对象”指定 geo_point
- 1.1.3、通过“字符串”指定 geo_point
- 1.1.4、通过“地理哈希”指定 geo_point
- 1.1.5、通过“数组”指定 geo_point
- 1.1.6、通过“WKT”指定 geo_point
- 1.2、geo_shape 地理形状类型
- 1.2.1、创建一个含有 geo_shape 字段的索引
- 1.2.2、通过 Point 指定单个地理坐标
- 1.2.3、通过 LineString 指定一条线
- 1.2.4、通过 Polygon 指定一个多边形
- 1.2.5、通过 MultiPoint 指定多个点
- 1.2.6、通过 MultiLineString 指定多条线
- 1.2.7、通过 MultiPolygon 指定多个多边形
- 1.2.8、通过 GeometryCollection 指定地理形状的集合
- 1.2.9、通过 envelope 指定矩形或包络线
- 1.2.10、通过 circle 指定圆形
- 二、地理查询
- 2.1、geo_bounding_box 矩形过滤
- 2.1.1、查询矩形内的定位点(文档)
- 2.2、geo_distance 距离查询(圆形过滤)
- 2.2.1、查询“附近的人”
- 2.2.2、查询“附近的人”并按距离排序
- 2.3、geo_polygon 多边形查询(已过时)
- 2.4、geo_shape 地理形状查询
- 2.4.1、查询 intersects 相交关系
- 2.4.2、查询 disjoint 不相交关系
- 2.4.3、查询 within 在...之内关系
- 2.4.4、查询 contains 包含关系
- 三、附录
- 附录一:es_location_001 索引
- 附录二:es_location_002 索引
- 附录三:地图工具
- 系列文章
- 热门专栏
大家好,我是水滴~~
地理信息查询是 Elasticsearch 的重要特性之一,其 GEO 功能主要用于地理信息的存储和搜索。本篇主要内容:介绍 Elasticsearch 的两种地理数据类型,并通过一些实例来讲述geo_bounding_box
查询、geo_distance
查询和 geo_shape
查询。
一、地理数据类型
在介绍地理查询前,我们先来了解下地理数据类型。Elasticsearch 支持两种地理数据类型:geo_point
和 geo_shape
。在之前的文章《Elasticsearch 核心技术(五):常用数据类型详解》中有介绍过,学过的友友可以跳过本章节。
注意:Elasticsearch 使用的是
WGS-84
坐标系,如果你是直接从高德地图中获取的经纬度坐标,需要转换一下再存储,否则会有精度问题。当然,如果对精度要求没有那么高,请忽略。
1.1、geo_point 地理点类型
geo_point
数据类型用来存储一个由经纬度组成的地理点,也就是地理坐标。
地理坐标在生活中有很多用处,比如:在一个陌生的城市,可以导航到指定的酒店;点外卖时可以查看附近有哪些好吃的;走累了可以看看哪里有共享单车等等。
1.1.1、创建一个含有 geo_point 字段的索引
下面示例创建一个 index_geo_point
索引,其中 location
字段为 geo_point
类型。
PUT index_geo_point
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
}
}
1.1.2、通过“对象”指定 geo_point
可以通过一个对象来表示地理点,其中 lat
表示纬度,lon
表示经度。
POST index_geo_point/_doc/1
{
"id": 1,
"location": {
"lat": 39.917846,
"lon": 116.397058
}
}
1.1.3、通过“字符串”指定 geo_point
可以通过一个字符串表示地理点,格式为:"lat, lon"
。
注意:字符串的地理点的顺序为 lat,lon,这与数组和WKT相反。
POST index_geo_point/_doc/2
{
"id": 2,
"location": "39.917846, 116.397058"
}
1.1.4、通过“地理哈希”指定 geo_point
可以通过地理点的哈希值来表示地理点。
POST index_geo_point/_doc/3
{
"id": 3,
"location": "drm3btev3e86"
}
1.1.5、通过“数组”指定 geo_point
可以通过一个数组来表示地理点,格式为:[lon, lat]
POST index_geo_point/_doc/4
{
"id": 4,
"location": [116.397058, 39.917846]
}
1.1.6、通过“WKT”指定 geo_point
可以通过 Well-Known Text 格式的 POINT
来表示地理点,格式为:"POINT(lon, lat)"
POST index_geo_point/_doc/5
{
"id": 5,
"location": "POINT(116.397058, 39.917846)"
}
1.2、geo_shape 地理形状类型
geo_shape
数据类型用于存储地理形状,例如:直线、矩形、多边形等。
也有很多场景只使用一个地理点是无法满足的,比如:一所学校、一处旅游景点、一座城市等等,想要表示这样大面积的地点,就需要用到 geo_shape
了。
下面一起看下 geo_shape
类型是如何指定的。
1.2.1、创建一个含有 geo_shape 字段的索引
下面示例创建一个 index_geo_shape
索引,其中 location
字段为 geo_shape
类型。
PUT index_geo_shape
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"location": {
"type": "geo_shape"
}
}
}
}
1.2.2、通过 Point 指定单个地理坐标
Point
类型用于指定单个地理坐标点,坐标数组格式为:[lon, lat]
POST index_geo_shape/_doc/1
{
"id": 1,
"location": {
"type": "Point",
"coordinates": [116.397058, 39.917846]
}
}
1.2.3、通过 LineString 指定一条线
LineString
类型用于指定一条线,该线由两个或多个位置点组成。
POST index_geo_shape/_doc/2
{
"id": 2,
"location": {
"type": "LineString",
"coordinates": [ [116.397058, 39.917846], [116.397058, 38.111111] ]
}
}
1.2.4、通过 Polygon 指定一个多边形
Polygon
类型用于指定一个多边形,该多边形要求第一个点和最后一个点必须相同,表示该多边形是闭合的。
POST index_geo_shape/_doc/3
{
"id": 3,
"location": {
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
]
}
}
这里要注意,
coordinates
是一个数组,表示可以指定多个多边形。
下面示例指定了两个多边形,一个数组表示多边形的外部边界,另一个数组表示多边形的内部边界,即表示一个带孔的多边形。
POST index_geo_shape/_doc/4
{
"id": 4,
"location" : {
"type" : "Polygon",
"coordinates" : [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
]
}
}
1.2.5、通过 MultiPoint 指定多个点
MultiPoint
类型用于指定多个点。
POST index_geo_shape/_doc/5
{
"id": 5,
"location" : {
"type" : "MultiPoint",
"coordinates" : [
[102.0, 2.0], [103.0, 2.0]
]
}
}
1.2.6、通过 MultiLineString 指定多条线
MultiLineString
类型用于指定多条线。
POST index_geo_shape/_doc/6
{
"id": 6,
"location" : {
"type" : "MultiLineString",
"coordinates" : [
[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0] ],
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8] ]
]
}
}
1.2.7、通过 MultiPolygon 指定多个多边形
MultiPolygon
类型用于指定多个多边形。
POST index_geo_shape/_doc/7
{
"id": 7,
"location" : {
"type" : "MultiPolygon",
"coordinates" : [
[ [[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]] ],
[ [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] ]
]
}
}
1.2.8、通过 GeometryCollection 指定地理形状的集合
GeometryCollection
类型用于指定一个地理形状的集合,即可以包含多个上面所属的地理形状。
POST index_geo_shape/_doc/8
{
"id": 8,
"location" : {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [100.0, 0.0]
},
{
"type": "LineString",
"coordinates": [ [101.0, 0.0], [102.0, 1.0] ]
}
]
}
}
1.2.9、通过 envelope 指定矩形或包络线
envelope
类型用于指定一个矩形或包络线,它由两个坐标组成,分别表示左上角和右下角的坐标。
POST index_geo_shape/_doc/9
{
"id": 9,
"location" : {
"type" : "envelope",
"coordinates" : [ [100.0, 1.0], [101.0, 0.0] ]
}
}
1.2.10、通过 circle 指定圆形
circle
类型用于指定一个圆形,需要指定圆心坐标和半径。
注意:映射字段时,圆形不能使用默认的策略,需要将
strategy
指定为recursive
。如下:
PUT index_geo_shape2
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"location": {
"type": "geo_shape",
"strategy": "recursive"
}
}
}
}
添加文档时,radius
用于指定半径,如果未指定单位,默认为米
POST index_geo_shape/_doc/10
{
"id": 10,
"location" : {
"type" : "circle",
"coordinates" : [101.0, 1.0],
"radius" : "100m"
}
}
二、地理查询
地理查询主要用于上文讲的两种地理数据类型 geo_point
和 geo_shape
的查询,查询的方法包括下面四种:geo_bounding_box
、geo_distance
、geo_polygon
和 geo_shape
。
下面我们分别介绍它们具体的应用。
2.1、geo_bounding_box 矩形过滤
geo_bounding_box
用于查询所有落入矩形的地理点所属文档。查询时需要指定两个坐标点左上角和右下角,这两个点就可以确定一个矩形,而查询的结果为,所有定位点落入该矩形的文档。
下面我们举例说明:
2.1.1、查询矩形内的定位点(文档)
我们以“故宫博物院”为例,取其左上角和右下角的坐标点,会形成一个矩形,然后查询该矩形内的坐标点(所属文档)。
上图中,故宫的左上角坐标点为
116.391978,39.922561
,右下角坐标点为116.402149,39.913443
。
另外找了 6 个点,分别代表 6 个文档的位置,它们的坐标点如下:
1:116.39775,39.92029
2:116.395947,39.916208
3:116.410624,39.91871
4:116.397235,39.909823
5:116.385304,39.917591
6:116.396548,39.92832
从肉眼可以看出,1 和 2 号坐标点在故宫的矩形框内,我们通过该实例,看能否准确的查出内容。
我们使用索引 es_location_001
演示该示例,索引的创建,及文档的添加请见附录一,这里我们只讲查询**。**
查询时需要指定
geo_bounding_box
类型,并指定top_left
左上角的坐标,bottom_right
右下角的坐标。
GET es_location_001/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 39.922561,
"lon": 116.391978
},
"bottom_right": {
"lat": 39.913443,
"lon": 116.402149
}
}
}
}
}
}
}
查询结果:通过查询结果可以看出 1、2 文档被查出,正是我们猜测的结果。
{
"took" : 929,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"id" : 1,
"location" : [
116.39775,
39.92029
]
}
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"id" : 2,
"location" : [
116.395947,
39.916208
]
}
}
]
}
}
2.2、geo_distance 距离查询(圆形过滤)
geo_distance
用于查询距离中心点指定范围内的地理点所属文档,也就是圆形过滤。查询时需要指定圆心的坐标,以及半径长度,就可以查询方圆内的文档了。
下面我们举例说明:
2.2.1、查询“附近的人”
我们还是使用 es_location_001
索引那 6 个坐标点来演示,而假设“我”当前的坐标为 116.410539,39.912983
,然后看下附近两公里内的人,如下图:
查询时需要指
geo_distance
并指定定圆心坐标(“我”的位置)和半径距离distance
GET /es_location_001/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": "2km",
"location": {
"lat": 39.912983,
"lon": 116.410539
}
}
}
}
}
}
查询结果:通过查询结果可以看出,1、2、3、4个点距离“我”在两公里内。
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"id" : 1,
"location" : [
116.39775,
39.92029
]
}
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"id" : 2,
"location" : [
116.395947,
39.916208
]
}
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"id" : 3,
"location" : [
116.410624,
39.91871
]
}
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"id" : 4,
"location" : [
116.397235,
39.909823
]
}
}
]
}
}
2.2.2、查询“附近的人”并按距离排序
上面的示例只显示了查询结果,并没有显示每个“人”距离“我”有多远,也没有排序。下面我们看怎么实现排序的。
按距离排序,需要在上面查询基础上增加
sort
选项,其中:_geo_distance
为“我”的坐标;order
指定asc
表示由近到远排序;unit
指定km
,表示结果显示的距离单位。
GET /es_location_001/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": "2km",
"location": {
"lat": 39.912983,
"lon": 116.410539
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 39.912983,
"lon": 116.410539
},
"order": "asc",
"unit": "km"
}
}
]
}
查询结果:查询结果便是按距离排序的结果,并且返回的 sort
选项为每个“人”距离“我”的距离
{
"took" : 26,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "3",
"_score" : null,
"_source" : {
"id" : 3,
"location" : [
116.410624,
39.91871
]
},
"sort" : [
0.6368510653173584
]
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "4",
"_score" : null,
"_source" : {
"id" : 4,
"location" : [
116.397235,
39.909823
]
},
"sort" : [
1.187873070108458
]
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "2",
"_score" : null,
"_source" : {
"id" : 2,
"location" : [
116.395947,
39.916208
]
},
"sort" : [
1.2951412302092007
]
},
{
"_index" : "es_location_001",
"_type" : "_doc",
"_id" : "1",
"_score" : null,
"_source" : {
"id" : 1,
"location" : [
116.39775,
39.92029
]
},
"sort" : [
1.360073305586383
]
}
]
}
}
2.3、geo_polygon 多边形查询(已过时)
在 7.12
版本中已弃用,官方推荐使用 geo_shape
。
2.4、geo_shape 地理形状查询
geo_shape
用于查询地理形状的空间关系。例如:与指定地理形状相交、包含、不相交的地理形状等。
而 Elasticsearch 支持四种空间关系:
intersects
:相交,用于查询所有与指定图形相交的文档。disjoint
:不相交,用于查询所有与指定图形不相交的文档。within
:在…之内,用于查询所有在指定图形之内的文档。contains
:包含,用于查询所有包含指定图形的文档。
下面我们举例说明:
我们先准备三个图形,我用的是矩形,如下图所示。并将它们添加到 es_location_002
索引中,索引的创建,及文档的添加请见附录二。
2.4.1、查询 intersects 相交关系
如下图,查询与蓝色三角形“相交”的图形有哪些,通过肉眼可以看出,1 和 2 与之相交。
查询相交的语句:
GET es_location_002/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "Polygon",
"coordinates": [
[ [116.382215,39.921606], [116.396892,39.919039], [116.387965,39.912719], [116.382215,39.921606] ]
]
},
"relation": "intersects"
}
}
}
}
}
}
查询结果:1 和 2 图形被查出,验证成功
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"id" : 2,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.391913,
39.922199
],
[
116.40187,
39.922396
],
[
116.402127,
39.91318
],
[
116.392085,
39.913114
],
[
116.391913,
39.922199
]
]
]
}
}
},
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"id" : 1,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.378009,
39.922199
],
[
116.385819,
39.92233
],
[
116.385819,
39.914958
],
[
116.378009,
39.914958
],
[
116.378009,
39.922199
]
]
]
}
}
}
]
}
}
2.4.2、查询 disjoint 不相交关系
还是刚才的蓝色三角形,查询与蓝色三角形“不相交”的图形有哪些,通过肉眼可以看出,3 与之不相交。
查询不相交的语句:
GET es_location_002/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "Polygon",
"coordinates": [
[ [116.382215,39.921606], [116.396892,39.919039], [116.387965,39.912719], [116.382215,39.921606] ]
]
},
"relation": "disjoint"
}
}
}
}
}
}
查询结果:3 图形被查询,验证成功
{
"took" : 115,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"id" : 3,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.407105,
39.923844
],
[
116.417405,
39.924437
],
[
116.417491,
39.912127
],
[
116.407277,
39.911863
],
[
116.407105,
39.923844
]
]
]
}
}
}
]
}
}
2.4.3、查询 within 在…之内关系
如下图,我画了一个大的蓝色矩形,将 1 和 2 包含在内,那么查询所有在蓝色矩形内的文档,看下 1 和 2 图形能否被查出。
查询在蓝色矩形之内语句:
GET es_location_002/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "Polygon",
"coordinates": [
[ [116.374404,39.92391], [116.404616,39.924108], [116.404359,39.911732], [116.374576,39.911337], [116.374404,39.92391] ]
]
},
"relation": "within"
}
}
}
}
}
}
查询结果:1 和 2 图形被查出
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"id" : 2,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.391913,
39.922199
],
[
116.40187,
39.922396
],
[
116.402127,
39.91318
],
[
116.392085,
39.913114
],
[
116.391913,
39.922199
]
]
]
}
}
},
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"id" : 1,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.378009,
39.922199
],
[
116.385819,
39.92233
],
[
116.385819,
39.914958
],
[
116.378009,
39.914958
],
[
116.378009,
39.922199
]
]
]
}
}
}
]
}
}
注意:在…之内关系也属于相交关系,通过查询相交的图形,也能查出 1 和 2 图形来。
查询相交语句:
GET es_location_002/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "Polygon",
"coordinates": [
[ [116.374404,39.92391], [116.404616,39.924108], [116.404359,39.911732], [116.374576,39.911337], [116.374404,39.92391] ]
]
},
"relation": "intersects"
}
}
}
}
}
}
查询结果:1 和 2 图形被查出
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"id" : 2,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.391913,
39.922199
],
[
116.40187,
39.922396
],
[
116.402127,
39.91318
],
[
116.392085,
39.913114
],
[
116.391913,
39.922199
]
]
]
}
}
},
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"id" : 1,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.378009,
39.922199
],
[
116.385819,
39.92233
],
[
116.385819,
39.914958
],
[
116.378009,
39.914958
],
[
116.378009,
39.922199
]
]
]
}
}
}
]
}
}
2.4.4、查询 contains 包含关系
如下图,在 3 图形内画了一个蓝色的三角形,查询所有包含三角形的文档,看能否将 3 图形查出来。
查询包含语句:
GET es_location_002/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "Polygon",
"coordinates": [
[ [116.41071,39.921014], [116.41483,39.917064], [116.409766,39.915748], [116.41071,39.921014] ]
]
},
"relation": "contains"
}
}
}
}
}
}
输出结果:3 图形被查出来
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"id" : 3,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.407105,
39.923844
],
[
116.417405,
39.924437
],
[
116.417491,
39.912127
],
[
116.407277,
39.911863
],
[
116.407105,
39.923844
]
]
]
}
}
}
]
}
}
注意:包含关系也属于相交关系,通过查询相交的图形,也能查出 3 图形来。
查询相交语句:
GET es_location_002/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "Polygon",
"coordinates": [
[ [116.41071,39.921014], [116.41483,39.917064], [116.409766,39.915748], [116.41071,39.921014] ]
]
},
"relation": "intersects"
}
}
}
}
}
}
查询结果:同样 3 图形被查询出来
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "es_location_002",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"id" : 3,
"location" : {
"type" : "Polygon",
"coordinates" : [
[
[
116.407105,
39.923844
],
[
116.417405,
39.924437
],
[
116.417491,
39.912127
],
[
116.407277,
39.911863
],
[
116.407105,
39.923844
]
]
]
}
}
}
]
}
}
三、附录
附录一:es_location_001 索引
创建 es_location_001
索引:
PUT es_location_001
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
}
}
添加 6 个文档:
POST es_location_001/_doc/1
{
"id": 1,
"location": [116.39775,39.92029]
}
POST es_location_001/_doc/2
{
"id": 2,
"location": [116.395947,39.916208]
}
POST es_location_001/_doc/3
{
"id": 3,
"location": [116.410624,39.91871]
}
POST es_location_001/_doc/4
{
"id": 4,
"location": [116.397235,39.909823]
}
POST es_location_001/_doc/5
{
"id": 5,
"location": [116.385304,39.917591]
}
POST es_location_001/_doc/6
{
"id": 6,
"location": [116.396548,39.92832]
}
附录二:es_location_002 索引
创建 es_location_002
索引:
PUT es_location_002
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"location": {
"type": "geo_shape"
}
}
}
}
添加 3 个矩形文档:
POST es_location_002/_doc/1
{
"id": 1,
"location": {
"type": "Polygon",
"coordinates": [
[ [116.378009,39.922199], [116.385819,39.92233], [116.385819,39.914958], [116.378009,39.914958], [116.378009,39.922199] ]
]
}
}
POST es_location_002/_doc/2
{
"id": 2,
"location": {
"type": "Polygon",
"coordinates": [
[ [116.391913,39.922199], [116.40187,39.922396], [116.402127,39.91318], [116.392085,39.913114], [116.391913,39.922199] ]
]
}
}
POST es_location_002/_doc/3
{
"id": 3,
"location": {
"type": "Polygon",
"coordinates": [
[ [116.407105,39.923844], [116.417405,39.924437], [116.417491,39.912127], [116.407277,39.911863], [116.407105,39.923844] ]
]
}
}
附录三:地图工具
-
高德坐标拾取器
-
坐标系转换
系列文章
🔥 Elasticsearch 核心技术(一):Elasticsearch 安装、配置、运行(Windows 版)
🔥 Elasticsearch 核心技术(二):elasticsearch-head 插件安装和使用
🔥 Elasticsearch 核心技术(三):Kibana 安装、配置、运行(Windows 版)
🔥 Elasticsearch 核心技术(四):索引管理、映射管理、文档管理(REST API)
🔥 Elasticsearch 核心技术(五):常用数据类型详解
🔥 Elasticsearch 核心技术(六):内置的 8 种分词器详解 + 代码示例
🔥 Elasticsearch 核心技术(七):IK 中文分词器的安装、使用、自定义字典
🔥 Elasticsearch 核心技术(八):常用 DSL 查询(全文搜索、精确匹配、布尔查询)
🔥 Elasticsearch 核心技术(九):搜索结果处理(分页、排序、指定返回字段、去重、高亮显示)
热门专栏
👍 《Python入门核心技术》
👍 《IDEA 教程:从入门到精通》
👍 《Java 教程:从入门到精通》
👍 《MySQL 教程:从入门到精通》
👍 《大数据核心技术从入门到精通》