本地英文版地址: ../en/query-dsl-geo-bounding-box-query.html
允许使用一个边界框基于点位置过滤命中的查询。假设以下索引的文档:
PUT /my_locations
{
"mappings": {
"properties": {
"pin": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
}
PUT /my_locations/_doc/1
{
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
}
}
然后,可以使用geo_bounding_box过滤器执行下面这个简单的查询:
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : {
"lat" : 40.73,
"lon" : -74.1
},
"bottom_right" : {
"lat" : 40.01,
"lon" : -71.12
}
}
}
}
}
}
}
查询选项
| 选项 | 描述 |
|---|---|
|
可选,用来标识过滤器名称的字段 |
|
设置为 |
|
设置为 |
接受的格式
与geo_point类型可以接受地理坐标点的不同表示方式非常相似,过滤器也可以接受它:
作为 lat lon 属性
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : {
"lat" : 40.73,
"lon" : -74.1
},
"bottom_right" : {
"lat" : 40.01,
"lon" : -71.12
}
}
}
}
}
}
}
作为 lat lon 数组
格式为[lon, lat],注意,此处 lon/lat 的顺序是为了符合GeoJSON。
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : [-74.1, 40.73],
"bottom_right" : [-71.12, 40.01]
}
}
}
}
}
}
作为 lat lon 字符串
格式为lat,lon。
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : "40.73, -74.1",
"bottom_right" : "40.01, -71.12"
}
}
}
}
}
}
作为众所周知的文本(Well-Known Text, WKT)的边界框
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"wkt" : "BBOX (-74.1, -71.12, 40.73, 40.01)"
}
}
}
}
}
}
geohash
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : "dr5r9ydj2y73",
"bottom_right" : "drj7teegpus6"
}
}
}
}
}
}
当 geohash 用于指定边界框的边界时,geohash 被视为矩形。
边界框的定义方式是:其左上角对应于top_left参数中指定的 geohash 的左上角,其右下角定义为bottom_right参数中指定的 geohash 的右下角。
为了指定与 geohash 的整个区域相匹配的边界框,可以在top_left和bottom_right参数中指定 geohash:
GET my_locations/_search
{
"query": {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : "dr",
"bottom_right" : "dr"
}
}
}
}
在本例中,geohash dr将生成边界框查询,其左上角为45.0,-78.75,右下角为39.375,-67.5。(为什么呢????)
顶点(Vertices)
边界框的顶点可以由top_left和bottom_right 或 top_right和bottom_left 参数设置。
除了这种下划线连接的名称格式,还支持小驼峰格式:topLeft、bottomRight、topRight 和 bottomLeft。
也可以使用简单的名称top、left、bottom和right来分别设置值,而不是成对设置值。
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top" : 40.73,
"left" : -74.1,
"bottom" : 40.01,
"right" : -71.12
}
}
}
}
}
}
geo_point 类型
过滤器要求在相关字段中设置geo_point类型。
一个文档包含多个位置
过滤器可以处理每个文档的多个位置/坐标点。 一旦单个位置/坐标点与过滤器匹配,该文档就将包含在过滤器中。
类型
默认情况下,边界框执行的类型设置为memory,这意味着在内存中检查文档是否落在边界框范围内。
在某些情况下,indexed选项的执行速度会更快(但请注意,在这种情况下,geo_point类型必须有 lat 和 lon 索引)。
请注意,使用indexed选项时,不支持文档的每个字段有多个位置。
这里有一个例子:
GET my_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : {
"lat" : 40.73,
"lon" : -74.1
},
"bottom_right" : {
"lat" : 40.10,
"lon" : -71.12
}
},
"type" : "indexed"
}
}
}
}
}
忽略未映射的字段 (ignore unmapped)
如果ignore_unmapped选项设置为true,将忽略未映射的字段,并且此查询不会匹配任何文档。
这在查询可能具有不同映射的多个索引时非常有用。
当设置为false(默认值)时,如果字段未映射,查询将抛出异常。
关于精度的提示
地理坐标点的精度有限,并且在索引时总是向下舍入。 在查询期间,边界框的上边界被向下舍入,而下边界被向上舍入。 因此,由于舍入误差,下边界(边界框的底部和左侧边缘)上的点可能不会进入边界框。 同时,沿着上边界(顶部和右侧边缘)的点可能被查询选中,即使它们位于边缘的稍外侧。 舍入误差在纬度上应小于4.20e-8度,在经度上应小于8.39e-8度,这意味着即使在赤道上误差也小于1厘米。