地理形状字段类型编辑

geo_shape 数据类型便于索引任意地理形状(例如矩形、线和多边形)并使用它们进行搜索。如果要索引的数据包含除点以外的其他形状,则必须使用此映射。如果数据仅包含点,则可以将其索引为 geo_pointgeo_shape

使用此类型的文档可以用于

不支持对 geo_shape 字段进行 geo_hex 网格的网格聚合。

映射选项编辑

geo_shape 映射将 GeoJSON 或 WKT 几何对象映射到 geo_shape 类型。要启用它,用户必须显式地将字段映射到 geo_shape 类型。

GeoJSONWKT 中,因此在 Elasticsearch 中,正确的 坐标顺序是经度、纬度(X、Y),位于坐标数组内。这与许多地理空间 API(例如 Google 地图)不同,后者通常使用口语化的纬度、经度(Y、X)。

选项 描述 默认值

orientation

可选。字段的 WKT 多边形的默认 方向

此参数仅设置和返回 RIGHT(逆时针)或 LEFT(顺时针)值。但是,您可以通过多种方式指定任一值。

要设置 RIGHT,请使用以下参数之一或其大写变体

  • right
  • counterclockwise
  • ccw

要设置 LEFT,请使用以下参数之一或其大写变体

  • left
  • clockwise
  • cw

RIGHT

ignore_malformed

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

false

ignore_z_value

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

true

coerce

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

false

index

该字段是否应该可以快速搜索?接受 true(默认值)和 false。仅启用了 doc_values 的字段仍然可以查询,但速度较慢。

true

doc_values

该字段是否应该以列跨度的方式存储在磁盘上,以便以后用于聚合或脚本?

true

索引方法编辑

地理形状类型通过将形状分解为三角形网格并在 BKD 树中将每个三角形索引为 7 维点来进行索引。这提供了近乎完美的空间分辨率(精确到 1e-7 十进制度),因为所有空间关系都是使用原始形状的编码向量表示来计算的。镶嵌器的性能主要取决于定义多边形/多边形的顶点数。

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

输入结构编辑

形状可以使用 GeoJSONWell-Known Text (WKT) 格式表示。下表提供了 GeoJSON 和 WKT 到 Elasticsearch 类型的映射

GeoJSON 类型 WKT 类型 Elasticsearch 类型 描述

Point

POINT

point

单个地理坐标。注意:Elasticsearch 仅使用 WGS-84 坐标。

LineString

LINESTRING

linestring

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

Polygon

POLYGON

polygon

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

MultiPoint

MULTIPOINT

multipoint

一组不连接但可能相关的点。

MultiLineString

MULTILINESTRING

multilinestring

一组独立的线串。

MultiPolygon

MULTIPOLYGON

multipolygon

一组独立的多边形。

GeometryCollection

GEOMETRYCOLLECTION

geometrycollection

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

N/A

BBOX

envelope

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

对于所有类型,内部 typecoordinates 字段都是必需的。

Point编辑

点是单个地理坐标,例如建筑物的位置或智能手机的 Geolocation API 提供的当前位置。以下是一个 GeoJSON 点的示例。

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

以下是一个 WKT 点的示例

response = client.index(
  index: 'example',
  body: {
    location: 'POINT (-77.03653 38.897676)'
  }
)
puts response
POST /example/_doc
{
  "location" : "POINT (-77.03653 38.897676)"
}
LineString编辑

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

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'LineString',
      coordinates: [
        [
          -77.03653,
          38.897676
        ],
        [
          -77.009051,
          38.889939
        ]
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "LineString",
    "coordinates" : [[-77.03653, 38.897676], [-77.009051, 38.889939]]
  }
}

以下是一个 WKT 线串的示例

response = client.index(
  index: 'example',
  body: {
    location: 'LINESTRING (-77.03653 38.897676, -77.009051 38.889939)'
  }
)
puts response
POST /example/_doc
{
  "location" : "LINESTRING (-77.03653 38.897676, -77.009051 38.889939)"
}

上面的线串将从白宫到美国国会大厦绘制一条直线。

Polygon编辑

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

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'Polygon',
      coordinates: [
        [
          [
            100,
            0
          ],
          [
            101,
            0
          ],
          [
            101,
            1
          ],
          [
            100,
            1
          ],
          [
            100,
            0
          ]
        ]
      ]
    }
  }
)
puts response
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 多边形的示例

response = client.index(
  index: 'example',
  body: {
    location: 'POLYGON ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0))'
  }
)
puts response
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 多边形的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'Polygon',
      coordinates: [
        [
          [
            100,
            0
          ],
          [
            101,
            0
          ],
          [
            101,
            1
          ],
          [
            100,
            1
          ],
          [
            100,
            0
          ]
        ],
        [
          [
            100.2,
            0.2
          ],
          [
            100.8,
            0.2
          ],
          [
            100.8,
            0.8
          ],
          [
            100.2,
            0.8
          ],
          [
            100.2,
            0.2
          ]
        ]
      ]
    }
  }
)
puts response
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 多边形的示例

response = client.index(
  index: 'example',
  body: {
    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))'
  }
)
puts response
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))"
}
多边形方向编辑

多边形的方向指示其顶点的顺序:RIGHT(逆时针)或 LEFT(顺时针)。Elasticsearch 使用多边形的方向来确定它是否跨越国际日期变更线(+/-180° 经度)。

您可以使用 orientation 映射参数 为 WKT 多边形设置默认方向。这是因为 WKT 规范没有指定或强制执行默认方向。

GeoJSON 多边形使用 RIGHT 的默认方向,无论 orientation 映射参数的值如何。这是因为 GeoJSON 规范 规定外部多边形使用逆时针方向,内部形状使用顺时针方向。

您可以使用文档级 orientation 参数覆盖 GeoJSON 多边形的默认方向。例如,以下索引请求指定了文档级 orientationLEFT

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'Polygon',
      orientation: 'LEFT',
      coordinates: [
        [
          [
            -177,
            10
          ],
          [
            176,
            15
          ],
          [
            172,
            0
          ],
          [
            176,
            -15
          ],
          [
            -177,
            -10
          ],
          [
            -177,
            10
          ]
        ]
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "Polygon",
    "orientation" : "LEFT",
    "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] ]
    ]
  }
}

Elasticsearch 仅使用多边形的方向来确定它是否跨越国际日期变更线。如果多边形的最小经度和最大经度之间的差小于 180°,则该多边形不会跨越日期变更线,其方向不会产生任何影响。

如果多边形的最小经度和最大经度之间的差为 180° 或更大,则 Elasticsearch 会检查多边形的文档级 orientation 是否与默认方向不同。如果方向不同,则 Elasticsearch 会认为该多边形跨越国际日期变更线并在日期变更线上拆分该多边形。

MultiPoint编辑

以下是一个 GeoJSON 点列表的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'MultiPoint',
      coordinates: [
        [
          102,
          2
        ],
        [
          103,
          2
        ]
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "MultiPoint",
    "coordinates" : [
      [102.0, 2.0], [103.0, 2.0]
    ]
  }
}

以下是一个 WKT 点列表的示例

response = client.index(
  index: 'example',
  body: {
    location: 'MULTIPOINT (102.0 2.0, 103.0 2.0)'
  }
)
puts response
POST /example/_doc
{
  "location" : "MULTIPOINT (102.0 2.0, 103.0 2.0)"
}
MultiLineString编辑

以下是一个 GeoJSON 线串列表的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'MultiLineString',
      coordinates: [
        [
          [
            102,
            2
          ],
          [
            103,
            2
          ],
          [
            103,
            3
          ],
          [
            102,
            3
          ]
        ],
        [
          [
            100,
            0
          ],
          [
            101,
            0
          ],
          [
            101,
            1
          ],
          [
            100,
            1
          ]
        ],
        [
          [
            100.2,
            0.2
          ],
          [
            100.8,
            0.2
          ],
          [
            100.8,
            0.8
          ],
          [
            100.2,
            0.8
          ]
        ]
      ]
    }
  }
)
puts response
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 线字符串列表的示例

response = client.index(
  index: 'example',
  body: {
    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))'
  }
)
puts response
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))"
}
多边形编辑

以下是 GeoJSON 多边形列表的示例(第二个多边形包含一个洞)

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'MultiPolygon',
      coordinates: [
        [
          [
            [
              102,
              2
            ],
            [
              103,
              2
            ],
            [
              103,
              3
            ],
            [
              102,
              3
            ],
            [
              102,
              2
            ]
          ]
        ],
        [
          [
            [
              100,
              0
            ],
            [
              101,
              0
            ],
            [
              101,
              1
            ],
            [
              100,
              1
            ],
            [
              100,
              0
            ]
          ],
          [
            [
              100.2,
              0.2
            ],
            [
              100.8,
              0.2
            ],
            [
              100.8,
              0.8
            ],
            [
              100.2,
              0.8
            ],
            [
              100.2,
              0.2
            ]
          ]
        ]
      ]
    }
  }
)
puts response
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 多边形列表的示例(第二个多边形包含一个洞)

response = client.index(
  index: 'example',
  body: {
    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)))'
  }
)
puts response
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)))"
}
几何图形集合编辑

以下是 GeoJSON 几何图形对象集合的示例

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'GeometryCollection',
      geometries: [
        {
          type: 'Point',
          coordinates: [
            100,
            0
          ]
        },
        {
          type: 'LineString',
          coordinates: [
            [
              101,
              0
            ],
            [
              102,
              1
            ]
          ]
        }
      ]
    }
  }
)
puts response
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 几何图形对象集合的示例

response = client.index(
  index: 'example',
  body: {
    location: 'GEOMETRYCOLLECTION (POINT (100.0 0.0), LINESTRING (101.0 0.0, 102.0 1.0))'
  }
)
puts response
POST /example/_doc
{
  "location" : "GEOMETRYCOLLECTION (POINT (100.0 0.0), LINESTRING (101.0 0.0, 102.0 1.0))"
}
包络编辑

Elasticsearch 支持 envelope 类型,它包含形状左上角和右下角点的坐标,以 [[minLon, maxLat], [maxLon, minLat]] 格式表示边界矩形

response = client.index(
  index: 'example',
  body: {
    location: {
      type: 'envelope',
      coordinates: [
        [
          100,
          1
        ],
        [
          101,
          0
        ]
      ]
    }
  }
)
puts response
POST /example/_doc
{
  "location" : {
    "type" : "envelope",
    "coordinates" : [ [100.0, 1.0], [101.0, 0.0] ]
  }
}

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

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

response = client.index(
  index: 'example',
  body: {
    location: 'BBOX (100.0, 102.0, 2.0, 0.0)'
  }
)
puts response
POST /example/_doc
{
  "location" : "BBOX (100.0, 102.0, 2.0, 0.0)"
}
圆形编辑

GeoJSON 和 WKT 都不支持点半径圆形类型。相反,请使用 圆形摄取处理器 将圆形近似为 polygon

排序和检索索引形状编辑

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