地理形状查询
使用地理形状查询来搜索包含 地理点(geopoint) 或 地理形状(geoshape) 字段的文档。你可以使用 查询中定义的地理形状 来过滤文档,或者使用 预索引的地理形状。
所搜索的文档字段必须映射为 geo_point
或 geo_shape
类型。
空间关系
当你向地理形状查询提供一个地理形状时,文档中的地理点和地理形状字段会使用以下空间关系与所提供的形状进行匹配。
关系 | 描述 | 支持的地理字段类型 |
---|---|---|
INTERSECTS | (默认)匹配文档中地理点或地理形状与查询中提供的形状相交的文档。 | geo_point , geo_shape |
DISJOINT | 匹配文档中地理形状与查询中提供的形状不相交的文档。 | geo_shape |
WITHIN | 匹配文档中地理形状完全位于查询中提供的形状内部的文档。 | geo_shape |
CONTAINS | 匹配文档中地理形状完全包含查询中提供的形状的文档。 | geo_shape |
在地理形状查询中定义形状
你可以在地理形状查询中定义形状以过滤文档,方法是 在查询时提供新的形状定义,或者 引用另一个索引中预索引形状的名称。
使用新的形状定义
要为地理形状查询提供新形状,请在 geo_shape
字段中定义它。你必须以 GeoJSON 格式 定义地理形状。
以下示例演示了搜索包含与查询时定义的地理形状匹配的地理形状的文档。
步骤 1:创建索引
首先,创建一个索引并将 location
字段映射为 geo_shape
PUT /testindex
{
"mappings": {
"properties": {
"location": {
"type": "geo_shape"
}
}
}
}
步骤 2:索引文档
索引一个包含点和一个包含多边形的文档
PUT testindex/_doc/1
{
"location": {
"type": "point",
"coordinates": [ 73.0515, 41.5582 ]
}
}
PUT testindex/_doc/2
{
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
步骤 3:运行地理形状查询
最后,定义一个地理形状来过滤文档。以下部分演示了在查询中提供各种地理形状。有关各种地理形状格式的更多信息,请参阅 地理形状字段类型。
包络
一个 envelope
是一个边界矩形,格式为 [[minLon, maxLat], [maxLon, minLat]]
。搜索包含与所提供的 `envelope` 相交的地理形状字段的文档。
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "envelope",
"coordinates": [
[
71.0589,
42.3601
],
[
74.006,
40.7128
]
]
},
"relation": "WITHIN"
}
}
}
}
响应包含这两个文档
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0,
"hits": [
{
"_index": "testindex",
"_id": "1",
"_score": 0,
"_source": {
"location": {
"type": "point",
"coordinates": [
73.0515,
41.5582
]
}
}
},
{
"_index": "testindex",
"_id": "2",
"_score": 0,
"_source": {
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
}
]
}
}
点
搜索其地理形状字段包含所提供点的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "point",
"coordinates": [
72.8000,
41.6300
]
},
"relation": "CONTAINS"
}
}
}
}
线串
搜索其地理形状字段与所提供的线串不相交的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "linestring",
"coordinates": [[74.0060, 40.7128], [71.0589, 42.3601]]
},
"relation": "DISJOINT"
}
}
}
}
线串地理形状查询不支持 WITHIN
关系。
多边形
在 GeoJSON 格式中,你必须以逆时针顺序列出多边形的顶点,并闭合多边形,使第一个顶点和最后一个顶点相同。
搜索其地理形状字段位于所提供多边形内部的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "polygon",
"coordinates": [
[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
]
]
},
"relation": "WITHIN"
}
}
}
}
多点
搜索其地理形状字段与所提供的点不相交的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "multipoint",
"coordinates" : [
[74.0060, 40.7128],
[71.0589, 42.3601]
]
},
"relation": "DISJOINT"
}
}
}
}
多线串
搜索其地理形状字段与所提供的线不相交的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "multilinestring",
"coordinates" : [
[[74.0060, 40.7128], [71.0589, 42.3601]],
[[73.7562, 42.6526], [72.6734, 41.7658]]
]
},
"relation": "disjoint"
}
}
}
}
多线串地理形状查询不支持 WITHIN
关系。
多多边形
搜索其地理形状字段位于所提供的多边形集合内部的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type" : "multipolygon",
"coordinates" : [
[
[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
],
[
[73.0515, 41.5582],
[72.6506, 41.5623],
[72.6734, 41.7658],
[73.0515, 41.5582]
]
],
[
[
[73.9146, 40.8252],
[73.8871, 41.0389],
[73.6853, 40.9747],
[73.9146, 40.8252]
]
]
]
},
"relation": "WITHIN"
}
}
}
}
几何集合
搜索其地理形状字段位于所提供的多边形内部的文档
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "geometrycollection",
"geometries": [
{
"type": "polygon",
"coordinates": [[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
]]
},
{
"type": "polygon",
"coordinates": [[
[73.0515, 41.5582],
[72.6506, 41.5623],
[72.6734, 41.7658],
[73.0515, 41.5582]
]]
}
]
},
"relation": "WITHIN"
}
}
}
}
几何集合包含线串或多线串的地理形状查询不支持 WITHIN
关系。
使用预索引的形状定义
构建地理形状查询时,你还可以引用另一个索引中预索引形状的名称。使用此方法,你可以在索引时定义一个地理形状,并在搜索时通过名称引用它。
你可以以 GeoJSON 或 Well-Known Text (WKT) 格式定义预索引的地理形状。有关各种地理形状格式的更多信息,请参阅 地理形状字段类型。
indexed_shape
对象支持以下参数。
参数 | 必需/可选 | 描述 |
---|---|---|
id | 必需 | 包含预索引形状的文档的文档 ID。 |
index | 可选 | 包含预索引形状的索引名称。默认为 shapes 。 |
路径 | 可选 | 包含预索引形状的字段的字段名(作为路径)。默认为 shape 。 |
路由 | 可选 | 包含预索引形状的文档的路由。 |
以下示例演示了如何引用另一个索引中预索引形状的名称。在此示例中,索引 pre-indexed-shapes
包含定义边界的形状,而索引 testindex
包含与这些边界进行检查的形状。
首先,创建 pre-indexed-shapes
索引,并将此索引的 boundaries
字段映射为 geo_shape
类型。
PUT /pre-indexed-shapes
{
"mappings": {
"properties": {
"boundaries": {
"type": "geo_shape",
"orientation" : "left"
}
}
}
}
有关为多边形指定不同顶点方向的更多信息,请参阅 多边形。
将指定搜索边界的多边形索引到 pre-indexed-shapes
索引中。该多边形的 ID 为 search_triangle
。在此示例中,你将以 WKT 格式索引该多边形。
PUT /pre-indexed-shapes/_doc/search_triangle
{
"boundaries":
"POLYGON ((74.0060 40.7128, 71.0589 42.3601, 73.7562 42.6526, 74.0060 40.7128))"
}
如果你尚未执行此操作,请将一个包含点的文档和另一个包含多边形的文档索引到 testindex
索引中。
PUT /testindex/_doc/1
{
"location": {
"type": "point",
"coordinates": [ 73.0515, 41.5582 ]
}
}
PUT /testindex/_doc/2
{
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
搜索其地理形状位于 search_triangle
内部的文档。
GET /testindex/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"indexed_shape": {
"index": "pre-indexed-shapes",
"id": "search_triangle",
"path": "boundaries"
},
"relation": "WITHIN"
}
}
}
}
}
}
响应包含这两个文档
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "testindex",
"_id": "1",
"_score": 1,
"_source": {
"location": {
"type": "point",
"coordinates": [
73.0515,
41.5582
]
}
}
},
{
"_index": "testindex",
"_id": "2",
"_score": 1,
"_source": {
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
}
]
}
}
查询地理点
你还可以使用地理形状查询来搜索包含地理点的文档。
geopoint
字段上的地理形状查询仅支持默认的 INTERSECTS
空间关系,因此你无需提供 relation
参数。
geopoint
字段上的地理形状查询不支持以下地理形状:
- 点
- 线串
- 多点
- 多线串
- 包含上述任一地理形状类型的几何集合
创建一个映射,其中 location
为 geo_point
类型。
PUT /testindex1
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
将两个点索引到该索引中。在此示例中,你将以字符串形式提供地理点坐标。
PUT /testindex1/_doc/1
{
"location": "41.5623, 72.6506"
}
PUT /testindex1/_doc/2
{
"location": "76.0254, 39.2467"
}
有关以各种格式提供地理点坐标的信息,请参阅 格式。
搜索与所提供多边形相交的地理点。
GET /testindex1/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "polygon",
"coordinates": [
[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
]
]
}
}
}
}
}
响应返回文档 1
{
"took": 21,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0,
"hits": [
{
"_index": "testindex1",
"_id": "1",
"_score": 0,
"_source": {
"location": "41.5623, 72.6506"
}
}
]
}
}
请注意,在索引地理点时,你以 "latitude, longitude"
格式指定了它们的坐标。当你搜索匹配文档时,坐标数组是 [longitude, latitude]
格式。因此,文档 1 在结果中返回,而文档 2 未返回。
参数
地理形状查询接受以下参数。
参数 | 数据类型 | 描述 |
---|---|---|
ignore_unmapped | 布尔型 | 指定是否忽略未映射的字段。如果设置为 true ,则查询不会返回任何包含未映射字段的文档。如果设置为 false ,则当字段未映射时会抛出异常。可选。默认为 false 。 |