本地英文版地址: ../en/geo-shape.html
geo_shape
数据类型便于索引和搜索任意地理形状,如矩形和多边形。
当被索引的数据或被执行的查询包含形状而不仅仅是坐标点时,应该使用它。
可以使用geo_shape查询来查询使用此类型的文档。
映射之选项
geo_shape 映射将 geo_json 几何对象映射到 geo_shape 类型。 要启用它,用户必须显式地将字段映射为 geo_shape 类型。
选项 | 描述 | 默认值 |
---|---|---|
|
[6.6]
在6.6版本中废弃。不再使用 前缀树(PrefixTree)。
要使用的PrefixTree实现的名称:实现 GeohashPrefixTree 的是 |
|
|
[6.6]
在6.6版本中废弃。不再使用 前缀树(PrefixTree)。
可以使用此参数代替 |
|
|
[6.6]
在6.6版本中废弃。不再使用 前缀树(PrefixTree)。
PrefixTree 可以使用的最大层数。
这可以用来控制形状表示的精度,从而控制索引的词项的数量。
默认为所选的 PrefixTree 实现的默认值。
由于此参数需要对底层实现有一定程度的了解,因此用户可以使用 |
various |
|
[6.6]
在6.6版本中废弃。不再使用 前缀树(PrefixTree)。
参数strategy定义了在编制索引和搜索时如何表示形状的方法。
它还会影响可用的功能,因此建议让 Elasticsearch 自动设置该参数。
有两种可用的参数: |
|
|
[6.6]
在6.6版本中废弃。不再使用 前缀树(PrefixTree)。
用作 PrefixTree 的暗示,告诉它应该有多精确。
默认值为 0.025 (2.5%),支持的最大值为 0.5。
性能说明:如果明确申明了 |
|
|
选择性地定义如何解释多边形/多重多边形的顶点顺序。
该参数定义了两个坐标系规则(右手 right-hand 或左手 left-hand)中的一个,每一个都可以用三种不同的方式指定。
1. 右手(right-hand) 规则: |
|
|
[6.6]
在6.6版本中废弃。不再使用 前缀树(PrefixTree)。
将此选项设置为 |
|
|
如果为 true,则忽略格式错误的 GeoJSON 或 WKT 形状。 如果为 false(默认值),格式错误的 GeoJSON 和 WKT 形状将导致异常并拒绝整个文档。 |
|
|
如果为 |
|
|
如果为 |
|
编制索引的方法
通过将形状分解成三角形网格并将每个三角形索引为 BKD 树中的 7 维点来索引 geo_shape 类型。
这提供了近乎完美的空间分辨率(低至1e-7十进制精度),因为所有空间关系都是使用原始形状的编码矢量表示来计算的,而不是前缀树(prefix trees)索引方法所使用的光栅网格表示。
镶嵌器的性能主要取决于定义多边形/多多边形的顶点数量。
虽然这是默认的索引技术,但是仍然可以通过根据适当的M映射选项设置tree
或strategy
参数来使用前缀树。
请注意,这些参数现在已被废弃,并将在未来版本中删除。
重要提示
CONTAINS
(包含) 关系查询 - 当使用新的默认向量索引策略时,使用7.5.0或更高版本的 ElasticSearch 创建的索引支持把relation
定义为contains
的geo_shape
查询。
前缀树(prefix trees)
[6.6] 在6.6版本中废弃。不再使用 前缀树(PrefixTree)。 为了在倒排索引中有效地表示形状,使用 PrefixTree (前缀树)的实现将形状转换为一系列表示网格正方形(通常称为 rasters, 即“栅格”)的哈希。 树的概念来自于 PrefixTree 使用多个网格层的事实,每个网格层都以越来越高的精度来表示 Earth(地球)。 这可以被认为是在更高的缩放级别下增加地图或图像的细节级别。 由于这种方法会导致索引的形状的精度问题,因此它已被弃用,取而代之的是将形状索引为三角形网格的矢量索引方法(参考索引方法)。
提供了多个 PrefixTree 实现方法:
- GeohashPrefixTree:将geohash(地理哈希)用于网格正方形。 geohash 是经纬度交织的 base32 编码的字符串。 添加到 geohash 的每个字符代表另一个树级别,并为 geohash 增加 5 比特位的精度。 geohash 表示一个矩形区域,有32个子矩形。 Elasticsearch中的最大级数为 24;默认值为 9。
- QuadPrefixTree:将quadtree(四叉树)用于网格正方形。 与 geohash 类似,quadtree(四叉树)交织纬度和经度的比特位,产生的哈希是一个比特位集。 四叉树中的树级别表示该比特位集中的 2 位,每个坐标一位。 Elasticsearch中四叉树的最大层数是 29;默认值为 21。
空间策略
[6.6] 在6.6版本中废弃。不再使用 前缀树(PrefixTree)。 所选择的索引实现方法依赖于选择如何分解形状(作为网格正方形或镶嵌的三角形网格)的空间策略。 每个策略回答以下问题:
- 什么类型的形状可以被索引?
- 可以使用哪些类型的查询操作和形状?
- 它是否支持每个字段有多个形状?
提供了以下策略实现方法(具有相应的功能):
精确度
recursive
和term
策略不能提供100%的准确性,并且根据它们的配置方式,它可能会为INTERSECTS
、WITHIN
和CONTAINS
查询返回一些假阳性,为DISJOINT
查询返回一些假阴性。
为了减轻这种情况,为参数 tree_levels 选择一个合适的值并相应地调整期望值是很重要的。
例如,某个点可能靠近特定网格单元的边界,因此可能与仅匹配其旁边单元的查询不匹配,即使形状非常接近该点。
示例
PUT /index_name { "mappings": { "properties": { "location": { "type": "geo_shape" } } } }
这个映射定义使用默认的矢量实现将 location 字段映射为 geo_shape 类型。 它提供大约 1e-7十进制的精度。
前缀树(prefix tree)的性能考量
[6.6] 在6.6版本中废弃。不再使用 前缀树(PrefixTree)。 使用前缀树,Elasticsearch 在倒排索引和查询中使用树中的路径作为词项。 级别越高(精度也越高),生成的词项就越多。 当然,计算这些词项,将它们保存在内存中,以及将它们存储在磁盘上都是有代价的。 尤其是在树级别较高的情况下,即使数据量不多,索引也会变得非常大。 此外,特征的大小也很重要。 大而复杂的多边形会在较高的树级别上占用大量空间。 哪个设置是正确的取决于用例。 通常,人们会在准确性与索引大小和查询性能之间进行权衡。
对于这两种实现,Elasticsearch中的默认值是索引大小和赤道上50米的合理精度之间的折衷。 允许对数千万个形状进行索引,而不会使结果索引相对于输入大小过于膨胀。
如果search.allow_expensive_queries
设置为 false,则不会对使用前缀树实现的地理形状执行 geo-shape 查询。
输入结构
可以使用GeoJSON或众所周知的文本 (WKT) 格式来表示形状。 下表提供了 GeoJSON 和 WKT 与 Elasticsearch 类型的映射:
GeoJSON 类型 | WKT 类型 | Elasticsearch 类型 | 描述 |
---|---|---|---|
|
|
|
一个地理坐标。注意:Elasticsearch 仅使用 WGS-84 坐标。 |
|
|
|
给定两点或多点的任意直线。 |
|
|
|
一个闭合的多边形,其第一个点和最后一个点必须匹配,因此需要 |
|
|
|
一组未连接但可能相关的点。 |
|
|
|
一组独立的直线。 |
|
|
|
一组独立的多边形。 |
|
|
|
类似于 |
|
|
|
通过仅指定左上角和右下角的点来指定的边界矩形或封套。 |
|
|
|
由圆心和半径指定的圆,其单位默认为 |
对于所有类型,内部type
和coordinates
(坐标)字段都是必需的。
在 GeoJSON 和 WKT 以及 Elasticsearch 中,坐标数组中正确的坐标顺序是经度(longitude)、纬度(latitude) (X,Y)。 这不同于许多地理空间API(例如Google Maps),它们通常使用通俗的纬度、经度(Y,X)。
Point
一个 point (点) 是一个地理坐标,比如一栋建筑的位置或者智能手机的 Geolocation API 给出的当前位置。 下面是 GeoJSON 中一个 point 的例子:
POST /example/_doc { "location" : { "type" : "point", "coordinates" : [-77.03653, 38.897676] } }
下面是 WKT 中一个 point 的例子:
POST /example/_doc { "location" : "POINT (-77.03653 38.897676)" }
LineString
由两个或多个位置的数组定义的linestring
。
通过仅指定两个点,linestring
将表示一条直线。
指定两个以上的点会创建任意路径。
下面是 GeoJSON 中一个 LineString 的例子:
POST /example/_doc { "location" : { "type" : "linestring", "coordinates" : [[-77.03653, 38.897676], [-77.009051, 38.889939]] } }
下面是 WKT 中一个 LineString 的例子:
POST /example/_doc { "location" : "LINESTRING (-77.03653 38.897676, -77.009051 38.889939)" }
上面的linestring
将画一条从白宫到美国国会大厦的直线。
Polygon
多边形是由一系列点定义的。 每个(外部)列表中的第一个和最后一个点必须相同(多边形必须是闭合的)。 下面是 GeoJSON 中一个 Polygon 的例子:
POST /example/_doc { "location" : { "type" : "polygon", "coordinates" : [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ] } }
下面是 WKT 中一个 Polygon 的例子:
POST /example/_doc { "location" : "POLYGON ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0))" }
第一个数组表示多边形的外部边界,其他数组表示内部形状(“孔”)。 下面是 GeoJSON 中一个有孔的 Polygon 的例子:
POST /example/_doc { "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] ] ] } }
下面是 WKT 中一个有孔的 Polygon 的例子:
POST /example/_doc { "location" : "POLYGON ((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))" }
重要提示:WKT 没有强制顶点的特定顺序,因此日期变更线和极点周围的多边形可能不明确。 GeoJSON要求外部多边形必须为逆时针方向,内部形状必须为顺时针方向,这符合开放地理空间联盟(Open Geospatial Consortium,OGC)关于顶点排序的简单特性访问规范。
如果顺时针和逆时针多边形看起来没有穿过日期变更线(即,它们穿过的经度小于180°),则 Elasticsearch 接受这两种多边形,但对于穿过日期变更线的多边形(或宽度大于180°的其他多边形), Elasticsearch 要求顶点排序符合 OGC 和 GeoJSON 规范。 否则,可能会创建非预期的多边形,并会返回意外的查询/过滤结果。
下面提供了一个不明确多边形的示例。 Elasticsearch 将应用 GeoJSON 标准来消除导致与日期变更线相交的多边形的模糊性。
POST /example/_doc { "location" : { "type" : "polygon", "coordinates" : [ [ [-177.0, 10.0], [176.0, 15.0], [172.0, 0.0], [176.0, -15.0], [-177.0, -10.0], [-177.0, 10.0] ], [ [178.2, 8.2], [-178.8, 8.2], [-180.8, -8.8], [178.2, 8.8] ] ] } }
设置 geo_shape 映射时,可以定义一个参数orientation
(请参见映射选项)。
这将为映射的 geo_shape 字段上的坐标列表定义顶点顺序。
它也可以在每个文档上被覆盖。
以下是一个覆盖文档上的方向的示例:
POST /example/_doc { "location" : { "type" : "polygon", "orientation" : "clockwise", "coordinates" : [ [ [100.0, 0.0], [100.0, 1.0], [101.0, 1.0], [101.0, 0.0], [100.0, 0.0] ] ] } }
MultiPoint
下面是一个 GeoJSON 格式 point 列表的示例:
POST /example/_doc { "location" : { "type" : "multipoint", "coordinates" : [ [102.0, 2.0], [103.0, 2.0] ] } }
下面是一个 WKT 格式 point 列表的示例:
POST /example/_doc { "location" : "MULTIPOINT (102.0 2.0, 103.0 2.0)" }
MultiLineString
下面是一个 GeoJSON 格式 linestring 列表的示例:
POST /example/_doc { "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] ] ] } }
下面是一个 WKT 格式 linestring 列表的示例:
POST /example/_doc { "location" : "MULTILINESTRING ((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))" }
MultiPolygon
下面是一个 GeoJSON 格式 polygon 列表的示例(第二个多边形包含一个孔):
POST /example/_doc { "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]] ] ] } }
下面是一个 WKT 格式 polygon 列表的示例(第二个多边形包含一个孔):
POST /example/_doc { "location" : "MULTIPOLYGON (((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)))" }
Geometry Collection
下面是一个 GeoJSON 格式 几何对象集合的示例:
POST /example/_doc { "location" : { "type": "geometrycollection", "geometries": [ { "type": "point", "coordinates": [100.0, 0.0] }, { "type": "linestring", "coordinates": [ [101.0, 0.0], [102.0, 1.0] ] } ] } }
下面是一个 WKT 格式 几何对象集合的示例:
POST /example/_doc { "location" : "GEOMETRYCOLLECTION (POINT (100.0 0.0), LINESTRING (101.0 0.0, 102.0 1.0))" }
envelope (边界矩形)
Elasticsearch 支持一种envelope
类型,它由形状的左上角和右下角的坐标组成,以[[minLon, maxLat], [maxLon, minLat]]
格式表示一个边界矩形:
POST /example/_doc { "location" : { "type" : "envelope", "coordinates" : [ [100.0, 1.0], [101.0, 0.0] ] } }
以下是使用 WKT BBOX 格式的 envelope 的示例:
注意: WKT规范要求以下顺序:minLon,maxLon,maxLat,minLat。
POST /example/_doc { "location" : "BBOX (100.0, 102.0, 2.0, 0.0)" }
circle (圆形)
Elasticsearch 支持一种circle
类型,由一个中心点和一个半径组成。
注意,只有在 前缀树(prefix tree) 使用recursive
策略时,才能对这个圆的表示进行索引。
对于默认的索引方法,circle 应该使用POLYGON
来近似表示。
POST /example/_doc { "location" : { "type" : "circle", "coordinates" : [101.0, 1.0], "radius" : "100m" } }
注意:内 radius
(半径) 字段是必需的。
如果半径的数值后面没有指定单位,那么半径的单位将默认为METERS
。
注意:GeoJSON和WKT都不支持点半径圆类型。 注意: GeoJSON 和 WKT 都不支持 point-radius circle 类型。
排序和检索索引形状
由于形状的复杂的输入结构和索引表示,目前无法对形状进行排序或直接检索它们的字段。
geo_shape 值只能通过_source
字段检索。