形状字段类型
编辑形状字段类型
编辑shape
数据类型有助于索引和搜索任意的 x, y
笛卡尔形状,例如矩形和多边形。它可以用于索引和查询坐标落在二维平面坐标系中的几何图形。
您可以使用 形状查询 来查询使用此类型的文档。
映射选项
编辑与 geo_shape
字段类型类似,shape
字段映射将 GeoJSON 或 Well-Known Text (WKT) 几何对象映射到形状类型。要启用它,用户必须显式地将字段映射到形状类型。
选项 | 描述 | 默认值 |
---|---|---|
|
可选择定义如何解释多边形/多多边形的顶点顺序。此参数定义两种坐标系规则(右手或左手),每种规则可以用三种不同的方式指定。1. 右手法则: |
|
|
如果为 true,则忽略格式错误的 GeoJSON 或 WKT 形状。如果为 false(默认),则格式错误的 GeoJSON 和 WKT 形状会抛出异常并拒绝整个文档。 |
|
|
如果为 |
|
|
如果为 |
|
索引方法
编辑与 geo_shape
类似,shape
字段类型的索引方法是将几何图形分解为三角形网格,并将每个三角形作为 BKD 树中的 7 维点进行索引。提供给索引器的坐标是单精度浮点值,因此该字段保证与 Java 虚拟机提供的精度相同(通常为 1E-38
)。对于多边形/多多边形,镶嵌器的性能主要取决于定义几何图形的顶点数。
重要提示
CONTAINS
关系查询 - 对于使用 ElasticSearch 7.5.0 或更高版本创建的索引,支持将 relation
定义为 contains
的 shape
查询。
示例
编辑resp = client.indices.create( index="example", mappings={ "properties": { "geometry": { "type": "shape" } } }, ) print(resp)
response = client.indices.create( index: 'example', body: { mappings: { properties: { geometry: { type: 'shape' } } } } ) puts response
const response = await client.indices.create({ index: "example", mappings: { properties: { geometry: { type: "shape", }, }, }, }); console.log(response);
PUT /example { "mappings": { "properties": { "geometry": { "type": "shape" } } } }
此映射定义将 geometry 字段映射到形状类型。索引器对顶点值使用单精度浮点数,因此精度保证与 Java 虚拟机提供的 float
值(大约为 1E-38)的精度相同。
输入结构
编辑可以使用 GeoJSON 或 Well-Known Text (WKT) 格式表示形状。下表提供了 GeoJSON 和 WKT 到 Elasticsearch 类型的映射
GeoJSON 类型 | WKT 类型 | Elasticsearch 类型 | 描述 |
---|---|---|---|
|
|
|
单个 |
|
|
|
由两个或多个点组成的任意线。 |
|
|
|
一个闭合的多边形,其第一个和最后一个点必须匹配,因此需要 |
|
|
|
一个不连接但可能相关的点的数组。 |
|
|
|
一个单独的线串数组。 |
|
|
|
一个单独的多边形数组。 |
|
|
|
一个类似于 |
|
|
|
一个边界矩形,或包络,仅通过指定左上角和右下角点来指定。 |
对于所有类型,内部 type
和 coordinates
字段都是必需的。
在 GeoJSON 和 WKT 中,因此在 Elasticsearch 中,正确的坐标顺序是 (X, Y) 在坐标数组中。这与许多通常使用口语化的纬度、经度 (Y, X) 排序的地理空间 API(例如,geo_shape
)不同。
点是笛卡尔 x, y
空间中的单个坐标。它可能表示虚拟世界或投影空间中感兴趣的项目的位置。以下是 GeoJSON 中点的示例。
resp = client.index( index="example", document={ "location": { "type": "point", "coordinates": [ -377.03653, 389.897676 ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'point', coordinates: [ -377.03653, 389.897676 ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "point", coordinates: [-377.03653, 389.897676], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "point", "coordinates" : [-377.03653, 389.897676] } }
以下是 WKT 中点的示例
resp = client.index( index="example", document={ "location": "POINT (-377.03653 389.897676)" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'POINT (-377.03653 389.897676)' } ) puts response
const response = await client.index({ index: "example", document: { location: "POINT (-377.03653 389.897676)", }, }); console.log(response);
POST /example/_doc { "location" : "POINT (-377.03653 389.897676)" }
由两个或多个位置数组定义的 linestring
。仅指定两个点时,linestring
将表示一条直线。指定两个以上的点将创建一个任意路径。以下是 GeoJSON 中 LineString 的示例。
resp = client.index( index="example", document={ "location": { "type": "linestring", "coordinates": [ [ -377.03653, 389.897676 ], [ -377.009051, 389.889939 ] ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'linestring', coordinates: [ [ -377.03653, 389.897676 ], [ -377.009051, 389.889939 ] ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "linestring", coordinates: [ [-377.03653, 389.897676], [-377.009051, 389.889939], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "linestring", "coordinates" : [[-377.03653, 389.897676], [-377.009051, 389.889939]] } }
以下是 WKT 中 LineString 的示例
resp = client.index( index="example", document={ "location": "LINESTRING (-377.03653 389.897676, -377.009051 389.889939)" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'LINESTRING (-377.03653 389.897676, -377.009051 389.889939)' } ) puts response
const response = await client.index({ index: "example", document: { location: "LINESTRING (-377.03653 389.897676, -377.009051 389.889939)", }, }); console.log(response);
POST /example/_doc { "location" : "LINESTRING (-377.03653 389.897676, -377.009051 389.889939)" }
多边形由点列表的列表定义。每个(外部)列表中的第一个和最后一个点必须相同(多边形必须闭合)。以下是 GeoJSON 中多边形的示例。
resp = client.index( index="example", document={ "location": { "type": "polygon", "coordinates": [ [ [ 1000, -1001 ], [ 1001, -1001 ], [ 1001, -1000 ], [ 1000, -1000 ], [ 1000, -1001 ] ] ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'polygon', coordinates: [ [ [ 1000, -1001 ], [ 1001, -1001 ], [ 1001, -1000 ], [ 1000, -1000 ], [ 1000, -1001 ] ] ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "polygon", coordinates: [ [ [1000, -1001], [1001, -1001], [1001, -1000], [1000, -1000], [1000, -1001], ], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "polygon", "coordinates" : [ [ [1000.0, -1001.0], [1001.0, -1001.0], [1001.0, -1000.0], [1000.0, -1000.0], [1000.0, -1001.0] ] ] } }
以下是 WKT 中多边形的示例
resp = client.index( index="example", document={ "location": "POLYGON ((1000.0 -1001.0, 1001.0 -1001.0, 1001.0 -1000.0, 1000.0 -1000.0, 1000.0 -1001.0))" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'POLYGON ((1000.0 -1001.0, 1001.0 -1001.0, 1001.0 -1000.0, 1000.0 -1000.0, 1000.0 -1001.0))' } ) puts response
const response = await client.index({ index: "example", document: { location: "POLYGON ((1000.0 -1001.0, 1001.0 -1001.0, 1001.0 -1000.0, 1000.0 -1000.0, 1000.0 -1001.0))", }, }); console.log(response);
POST /example/_doc { "location" : "POLYGON ((1000.0 -1001.0, 1001.0 -1001.0, 1001.0 -1000.0, 1000.0 -1000.0, 1000.0 -1001.0))" }
第一个数组表示多边形的外边界,其他数组表示内部形状(“孔”)。以下是带有孔的多边形的 GeoJSON 示例
resp = client.index( index="example", document={ "location": { "type": "polygon", "coordinates": [ [ [ 1000, -1001 ], [ 1001, -1001 ], [ 1001, -1000 ], [ 1000, -1000 ], [ 1000, -1001 ] ], [ [ 1000.2, -1001.2 ], [ 1000.8, -1001.2 ], [ 1000.8, -1001.8 ], [ 1000.2, -1001.8 ], [ 1000.2, -1001.2 ] ] ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'polygon', coordinates: [ [ [ 1000, -1001 ], [ 1001, -1001 ], [ 1001, -1000 ], [ 1000, -1000 ], [ 1000, -1001 ] ], [ [ 1000.2, -1001.2 ], [ 1000.8, -1001.2 ], [ 1000.8, -1001.8 ], [ 1000.2, -1001.8 ], [ 1000.2, -1001.2 ] ] ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "polygon", coordinates: [ [ [1000, -1001], [1001, -1001], [1001, -1000], [1000, -1000], [1000, -1001], ], [ [1000.2, -1001.2], [1000.8, -1001.2], [1000.8, -1001.8], [1000.2, -1001.8], [1000.2, -1001.2], ], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "polygon", "coordinates" : [ [ [1000.0, -1001.0], [1001.0, -1001.0], [1001.0, -1000.0], [1000.0, -1000.0], [1000.0, -1001.0] ], [ [1000.2, -1001.2], [1000.8, -1001.2], [1000.8, -1001.8], [1000.2, -1001.8], [1000.2, -1001.2] ] ] } }
以下是 WKT 中带有孔的多边形的示例
resp = client.index( index="example", document={ "location": "POLYGON ((1000.0 1000.0, 1001.0 1000.0, 1001.0 1001.0, 1000.0 1001.0, 1000.0 1000.0), (1000.2 1000.2, 1000.8 1000.2, 1000.8 1000.8, 1000.2 1000.8, 1000.2 1000.2))" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'POLYGON ((1000.0 1000.0, 1001.0 1000.0, 1001.0 1001.0, 1000.0 1001.0, 1000.0 1000.0), (1000.2 1000.2, 1000.8 1000.2, 1000.8 1000.8, 1000.2 1000.8, 1000.2 1000.2))' } ) puts response
const response = await client.index({ index: "example", document: { location: "POLYGON ((1000.0 1000.0, 1001.0 1000.0, 1001.0 1001.0, 1000.0 1001.0, 1000.0 1000.0), (1000.2 1000.2, 1000.8 1000.2, 1000.8 1000.8, 1000.2 1000.8, 1000.2 1000.2))", }, }); console.log(response);
POST /example/_doc { "location" : "POLYGON ((1000.0 1000.0, 1001.0 1000.0, 1001.0 1001.0, 1000.0 1001.0, 1000.0 1000.0), (1000.2 1000.2, 1000.8 1000.2, 1000.8 1000.8, 1000.2 1000.8, 1000.2 1000.2))" }
重要提示:WKT 不强制指定顶点的特定顺序。GeoJSON 规定外多边形必须是逆时针方向,内部形状必须是顺时针方向,这与开放地理空间联盟 (OGC) 的 简单要素访问 规范中规定的顶点顺序一致。
默认情况下,Elasticsearch 期望顶点按逆时针(右手法则)顺序排列。如果数据按顺时针顺序(左手法则)提供,则用户可以更改字段映射中的 orientation
参数,或作为文档提供的参数。
以下是覆盖文档中的 orientation
参数的示例
resp = client.index( index="example", document={ "location": { "type": "polygon", "orientation": "clockwise", "coordinates": [ [ [ 1000, 1000 ], [ 1000, 1001 ], [ 1001, 1001 ], [ 1001, 1000 ], [ 1000, 1000 ] ] ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'polygon', orientation: 'clockwise', coordinates: [ [ [ 1000, 1000 ], [ 1000, 1001 ], [ 1001, 1001 ], [ 1001, 1000 ], [ 1000, 1000 ] ] ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "polygon", orientation: "clockwise", coordinates: [ [ [1000, 1000], [1000, 1001], [1001, 1001], [1001, 1000], [1000, 1000], ], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "polygon", "orientation" : "clockwise", "coordinates" : [ [ [1000.0, 1000.0], [1000.0, 1001.0], [1001.0, 1001.0], [1001.0, 1000.0], [1000.0, 1000.0] ] ] } }
以下是 GeoJSON 点列表的示例
resp = client.index( index="example", document={ "location": { "type": "multipoint", "coordinates": [ [ 1002, 1002 ], [ 1003, 2000 ] ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'multipoint', coordinates: [ [ 1002, 1002 ], [ 1003, 2000 ] ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "multipoint", coordinates: [ [1002, 1002], [1003, 2000], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "multipoint", "coordinates" : [ [1002.0, 1002.0], [1003.0, 2000.0] ] } }
以下是 WKT 点列表的示例
resp = client.index( index="example", document={ "location": "MULTIPOINT (1002.0 2000.0, 1003.0 2000.0)" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'MULTIPOINT (1002.0 2000.0, 1003.0 2000.0)' } ) puts response
const response = await client.index({ index: "example", document: { location: "MULTIPOINT (1002.0 2000.0, 1003.0 2000.0)", }, }); console.log(response);
POST /example/_doc { "location" : "MULTIPOINT (1002.0 2000.0, 1003.0 2000.0)" }
以下是 GeoJSON 线串列表的示例
resp = client.index( index="example", document={ "location": { "type": "multilinestring", "coordinates": [ [ [ 1002, 200 ], [ 1003, 200 ], [ 1003, 300 ], [ 1002, 300 ] ], [ [ 1000, 100 ], [ 1001, 100 ], [ 1001, 100 ], [ 1000, 100 ] ], [ [ 1000.2, 100.2 ], [ 1000.8, 100.2 ], [ 1000.8, 100.8 ], [ 1000.2, 100.8 ] ] ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'multilinestring', coordinates: [ [ [ 1002, 200 ], [ 1003, 200 ], [ 1003, 300 ], [ 1002, 300 ] ], [ [ 1000, 100 ], [ 1001, 100 ], [ 1001, 100 ], [ 1000, 100 ] ], [ [ 1000.2, 100.2 ], [ 1000.8, 100.2 ], [ 1000.8, 100.8 ], [ 1000.2, 100.8 ] ] ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "multilinestring", coordinates: [ [ [1002, 200], [1003, 200], [1003, 300], [1002, 300], ], [ [1000, 100], [1001, 100], [1001, 100], [1000, 100], ], [ [1000.2, 100.2], [1000.8, 100.2], [1000.8, 100.8], [1000.2, 100.8], ], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "multilinestring", "coordinates" : [ [ [1002.0, 200.0], [1003.0, 200.0], [1003.0, 300.0], [1002.0, 300.0] ], [ [1000.0, 100.0], [1001.0, 100.0], [1001.0, 100.0], [1000.0, 100.0] ], [ [1000.2, 100.2], [1000.8, 100.2], [1000.8, 100.8], [1000.2, 100.8] ] ] } }
以下是 WKT 线串列表的示例
resp = client.index( index="example", document={ "location": "MULTILINESTRING ((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0), (1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0), (1000.2 0.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8))" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'MULTILINESTRING ((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0), (1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0), (1000.2 0.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8))' } ) puts response
const response = await client.index({ index: "example", document: { location: "MULTILINESTRING ((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0), (1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0), (1000.2 0.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8))", }, }); console.log(response);
POST /example/_doc { "location" : "MULTILINESTRING ((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0), (1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0), (1000.2 0.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8))" }
以下是 GeoJSON 多边形列表的示例(第二个多边形包含一个孔)
resp = client.index( index="example", document={ "location": { "type": "multipolygon", "coordinates": [ [ [ [ 1002, 200 ], [ 1003, 200 ], [ 1003, 300 ], [ 1002, 300 ], [ 1002, 200 ] ] ], [ [ [ 1000, 200 ], [ 1001, 100 ], [ 1001, 100 ], [ 1000, 100 ], [ 1000, 100 ] ], [ [ 1000.2, 200.2 ], [ 1000.8, 100.2 ], [ 1000.8, 100.8 ], [ 1000.2, 100.8 ], [ 1000.2, 100.2 ] ] ] ] } }, ) print(resp)
const response = await client.index({ index: "example", document: { location: { type: "multipolygon", coordinates: [ [ [ [1002, 200], [1003, 200], [1003, 300], [1002, 300], [1002, 200], ], ], [ [ [1000, 200], [1001, 100], [1001, 100], [1000, 100], [1000, 100], ], [ [1000.2, 200.2], [1000.8, 100.2], [1000.8, 100.8], [1000.2, 100.8], [1000.2, 100.2], ], ], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "multipolygon", "coordinates" : [ [ [[1002.0, 200.0], [1003.0, 200.0], [1003.0, 300.0], [1002.0, 300.0], [1002.0, 200.0]] ], [ [[1000.0, 200.0], [1001.0, 100.0], [1001.0, 100.0], [1000.0, 100.0], [1000.0, 100.0]], [[1000.2, 200.2], [1000.8, 100.2], [1000.8, 100.8], [1000.2, 100.8], [1000.2, 100.2]] ] ] } }
以下是 WKT 多边形列表的示例(第二个多边形包含一个孔)
resp = client.index( index="example", document={ "location": "MULTIPOLYGON (((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0, 102.0 200.0)), ((1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0, 1000.0 100.0), (1000.2 100.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8, 1000.2 100.2)))" }, ) print(resp)
const response = await client.index({ index: "example", document: { location: "MULTIPOLYGON (((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0, 102.0 200.0)), ((1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0, 1000.0 100.0), (1000.2 100.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8, 1000.2 100.2)))", }, }); console.log(response);
POST /example/_doc { "location" : "MULTIPOLYGON (((1002.0 200.0, 1003.0 200.0, 1003.0 300.0, 1002.0 300.0, 102.0 200.0)), ((1000.0 100.0, 1001.0 100.0, 1001.0 100.0, 1000.0 100.0, 1000.0 100.0), (1000.2 100.2, 1000.8 100.2, 1000.8 100.8, 1000.2 100.8, 1000.2 100.2)))" }
以下是 GeoJSON 几何对象集合的示例
resp = client.index( index="example", document={ "location": { "type": "geometrycollection", "geometries": [ { "type": "point", "coordinates": [ 1000, 100 ] }, { "type": "linestring", "coordinates": [ [ 1001, 100 ], [ 1002, 100 ] ] } ] } }, ) print(resp)
response = client.index( index: 'example', body: { location: { type: 'geometrycollection', geometries: [ { type: 'point', coordinates: [ 1000, 100 ] }, { type: 'linestring', coordinates: [ [ 1001, 100 ], [ 1002, 100 ] ] } ] } } ) puts response
const response = await client.index({ index: "example", document: { location: { type: "geometrycollection", geometries: [ { type: "point", coordinates: [1000, 100], }, { type: "linestring", coordinates: [ [1001, 100], [1002, 100], ], }, ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type": "geometrycollection", "geometries": [ { "type": "point", "coordinates": [1000.0, 100.0] }, { "type": "linestring", "coordinates": [ [1001.0, 100.0], [1002.0, 100.0] ] } ] } }
以下是 WKT 几何对象集合的示例
resp = client.index( index="example", document={ "location": "GEOMETRYCOLLECTION (POINT (1000.0 100.0), LINESTRING (1001.0 100.0, 1002.0 100.0))" }, ) print(resp)
response = client.index( index: 'example', body: { location: 'GEOMETRYCOLLECTION (POINT (1000.0 100.0), LINESTRING (1001.0 100.0, 1002.0 100.0))' } ) puts response
const response = await client.index({ index: "example", document: { location: "GEOMETRYCOLLECTION (POINT (1000.0 100.0), LINESTRING (1001.0 100.0, 1002.0 100.0))", }, }); console.log(response);
POST /example/_doc { "location" : "GEOMETRYCOLLECTION (POINT (1000.0 100.0), LINESTRING (1001.0 100.0, 1002.0 100.0))" }
包络
编辑Elasticsearch 支持 envelope
类型,该类型由形状的左上角和右下角点的坐标组成,以 [[minX, maxY], [maxX, minY]]
格式表示边界矩形。
resp = client.index( index="example", document={ "location": { "type": "envelope", "coordinates": [ [ 1000, 100 ], [ 1001, 100 ] ] } }, ) print(resp)
const response = await client.index({ index: "example", document: { location: { type: "envelope", coordinates: [ [1000, 100], [1001, 100], ], }, }, }); console.log(response);
POST /example/_doc { "location" : { "type" : "envelope", "coordinates" : [ [1000.0, 100.0], [1001.0, 100.0] ] } }
以下是使用 WKT BBOX 格式的包络示例
注意:WKT 规范期望以下顺序:minLon、maxLon、maxLat、minLat。
resp = client.index( index="example", document={ "location": "BBOX (1000.0, 1002.0, 2000.0, 1000.0)" }, ) print(resp)
const response = await client.index({ index: "example", document: { location: "BBOX (1000.0, 1002.0, 2000.0, 1000.0)", }, }); console.log(response);
POST /example/_doc { "location" : "BBOX (1000.0, 1002.0, 2000.0, 1000.0)" }
排序和检索索引形状
编辑由于形状的输入结构和索引表示复杂,目前无法对形状进行排序或直接检索其字段。shape
值只能通过 _source
字段检索。