形状字段类型编辑

shape 数据类型有助于对任意 x, y 笛卡尔形状(如矩形和多边形)进行索引和搜索。它可以用来索引和查询坐标落在二维平面坐标系中的几何图形。

您可以使用 形状查询 查询此类型的文档。

映射选项编辑

geo_shape 字段类型类似,shape 字段映射将 GeoJSON知名文本 (WKT) 几何对象映射到形状类型。要启用它,用户必须显式地将字段映射到形状类型。

选项 描述 默认值

orientation

可选地定义如何解释多边形/多面体的顶点顺序。此参数定义了两种坐标系规则之一(右手或左手),每种规则可以用三种不同的方式指定。1. 右手规则:rightccwcounterclockwise,2. 左手规则:leftcwclockwise。默认方向 (counterclockwise) 符合 OGC 标准,该标准定义外环顶点按逆时针顺序排列,内环顶点(孔)按顺时针顺序排列。在 geo_shape 映射中设置此参数将显式地设置 geo_shape 字段的坐标列表的顶点顺序,但可以在每个 GeoJSON 或 WKT 文档中覆盖此参数。

ccw

ignore_malformed

如果为 true,则忽略格式错误的 GeoJSON 或 WKT 形状。如果为 false(默认值),则格式错误的 GeoJSON 和 WKT 形状将引发异常并拒绝整个文档。

false

ignore_z_value

如果为 true(默认值),则接受三维点(存储在源中),但只索引纬度和经度值;第三维将被忽略。如果为 false,则包含任何超过纬度和经度(二维)值的地理点将引发异常并拒绝整个文档。

true

coerce

如果为 true,则多边形中未闭合的线性环将自动闭合。

false

索引方法编辑

geo_shape 类似,shape 字段类型是通过将几何图形分解成三角形网格,并将每个三角形作为 7 维点索引到 BKD 树中来索引的。提供给索引器的坐标是单精度浮点值,因此该字段保证与 Java 虚拟机提供的精度相同(通常为 1E-38)。对于多边形/多面体,镶嵌器的性能主要取决于定义几何图形的顶点数。

重要说明

CONTAINS 关系查询 - 对于使用 ElasticSearch 7.5.0 或更高版本创建的索引,支持 relation 定义为 containsshape 查询。

示例编辑
response = client.indices.create(
  index: 'example',
  body: {
    mappings: {
      properties: {
        geometry: {
          type: 'shape'
        }
      }
    }
  }
)
puts response
PUT /example
{
  "mappings": {
    "properties": {
      "geometry": {
        "type": "shape"
      }
    }
  }
}

此映射定义将 geometry 字段映射到形状类型。索引器对顶点值使用单精度浮点数,因此精度保证与 Java 虚拟机提供的 float 值的精度大致相同(通常为 1E-38)。

输入结构编辑

可以使用 GeoJSON知名文本 (WKT) 格式表示形状。下表提供了 GeoJSON 和 WKT 到 Elasticsearch 类型的映射

GeoJSON 类型 WKT 类型 Elasticsearch 类型 描述

Point

POINT

point

单个 x, y 坐标。

LineString

LINESTRING

linestring

由两个或多个点给定的任意线。

Polygon

POLYGON

polygon

一个*闭合*多边形,其第一个和最后一个点必须匹配,因此需要 n + 1 个顶点来创建一个 n 边形,并且至少需要 4 个顶点。

MultiPoint

MULTIPOINT

multipoint

一个未连接但可能相关的点的数组。

MultiLineString

MULTILINESTRING

multilinestring

一个单独的线串数组。

MultiPolygon

MULTIPOLYGON

multipolygon

一个单独的多边形数组。

GeometryCollection

GEOMETRYCOLLECTION

geometrycollection

一个类似于 multi* 形状的形状集合,但可以共存多种类型(例如,一个点和一个线串)。

不适用

BBOX

envelope

一个边界矩形或包络线,仅通过指定左上角和右下角的点来指定。

对于所有类型,都需要内部 typecoordinates 字段。

在 GeoJSON 和 WKT 中,以及 Elasticsearch 中,正确的 坐标顺序是 (X, Y) 在坐标数组中。这与许多地理空间 API(例如,geo_shape)不同,后者通常使用口语化的纬度、经度 (Y, X) 顺序。

编辑

点是笛卡尔 x, y 空间中的单个坐标。它可以表示虚拟世界或投影空间中感兴趣项目的的位置。以下是 GeoJSON 中的一个点示例。

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'point',
      coordinates: [
        -377.03653,
        389.897676
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "point",
    "coordinates" : [-377.03653, 389.897676]
  }
}

以下是 WKT 中的一个点示例

response = client.index(
  index: 'example',
  body: {
    location: 'POINT (-377.03653 389.897676)'
  }
)
puts response
POST /example/_doc
{
  "location" : "POINT (-377.03653 389.897676)"
}
线串编辑

由两个或多个位置的数组定义的 linestring。通过仅指定两个点,linestring 将表示一条直线。指定两个以上的点将创建一条任意路径。以下是 GeoJSON 中的一个 LineString 示例。

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'linestring',
      coordinates: [
        [
          -377.03653,
          389.897676
        ],
        [
          -377.009051,
          389.889939
        ]
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "linestring",
    "coordinates" : [[-377.03653, 389.897676], [-377.009051, 389.889939]]
  }
}

以下是 WKT 中的一个 LineString 示例

response = client.index(
  index: 'example',
  body: {
    location: 'LINESTRING (-377.03653 389.897676, -377.009051 389.889939)'
  }
)
puts response
POST /example/_doc
{
  "location" : "LINESTRING (-377.03653 389.897676, -377.009051 389.889939)"
}
多边形编辑

多边形由一个点的列表定义。每个(外部)列表中的第一个和最后一个点必须相同(多边形必须闭合)。以下是 GeoJSON 中的一个 Polygon 示例。

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'polygon',
      coordinates: [
        [
          [
            1000,
            -1001
          ],
          [
            1001,
            -1001
          ],
          [
            1001,
            -1000
          ],
          [
            1000,
            -1000
          ],
          [
            1000,
            -1001
          ]
        ]
      ]
    }
  }
)
puts 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 中的一个 Polygon 示例

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
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 中的一个带孔的多边形示例

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
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 中的一个带孔的多边形示例

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
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 参数的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'polygon',
      orientation: 'clockwise',
      coordinates: [
        [
          [
            1000,
            1000
          ],
          [
            1000,
            1001
          ],
          [
            1001,
            1001
          ],
          [
            1001,
            1000
          ],
          [
            1000,
            1000
          ]
        ]
      ]
    }
  }
)
puts 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 点列表的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'multipoint',
      coordinates: [
        [
          1002,
          1002
        ],
        [
          1003,
          2000
        ]
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "multipoint",
    "coordinates" : [
      [1002.0, 1002.0], [1003.0, 2000.0]
    ]
  }
}

以下是 WKT 点列表的示例

response = client.index(
  index: 'example',
  body: {
    location: 'MULTIPOINT (1002.0 2000.0, 1003.0 2000.0)'
  }
)
puts response
POST /example/_doc
{
  "location" : "MULTIPOINT (1002.0 2000.0, 1003.0 2000.0)"
}
多线串编辑

以下是 GeoJSON 线串列表的示例

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
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 线串列表的示例

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
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 多边形列表的示例(第二个多边形包含一个孔)

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 多边形列表的示例(第二个多边形包含一个孔)

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 几何对象集合的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'geometrycollection',
      geometries: [
        {
          type: 'point',
          coordinates: [
            1000,
            100
          ]
        },
        {
          type: 'linestring',
          coordinates: [
            [
              1001,
              100
            ],
            [
              1002,
              100
            ]
          ]
        }
      ]
    }
  }
)
puts 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 几何对象集合的示例

response = client.index(
  index: 'example',
  body: {
    location: 'GEOMETRYCOLLECTION (POINT (1000.0 100.0), LINESTRING (1001.0 100.0, 1002.0 100.0))'
  }
)
puts 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]] 格式的边界矩形

POST /example/_doc
{
  "location" : {
    "type" : "envelope",
    "coordinates" : [ [1000.0, 100.0], [1001.0, 100.0] ]
  }
}

以下是使用 WKT BBOX 格式的包络线示例

注意: WKT 规范期望以下顺序:minLon、maxLon、maxLat、minLat。

POST /example/_doc
{
  "location" : "BBOX (1000.0, 1002.0, 2000.0, 1000.0)"
}

排序和检索索引形状编辑

由于形状的复杂输入结构和索引表示,目前无法对形状进行排序或直接检索其字段。shape 值只能通过 _source 字段检索。