geohash网格(geohash_grid)聚合

一个多桶聚合,作用于 geo_point 字段,并将坐标点分组到代表网格单元格的桶中。 生成的网格可以是稀疏的,只包含具有匹配数据的单元格。 每个单元格都使用用户可定义精度的geohash进行标注。

  • 高精度 geohash 的字符串长度比较长,表示仅覆盖很小区域的单元格。
  • 低精度 geohash 的字符串长度比较短,表示每个覆盖较大区域的单元格。

此聚合中使用的 geohash 的精度可在1和12之间选择。

长度为12的最高精度的 geohash 生成的单元格覆盖的土地面积不到一平方米,因此高精度请求在内存和结果大小方面的成本非常高。 请看下面的示例,了解如何在请求高精度的详细信息之前,先将聚合过滤到较小的地理区域。

指定字段的类型必须是geo_point (只能在映射中显式设置),它还可以保存一个geo_point字段数组,在这种情况下,所有这些都将在聚合过程中考虑在内。

简单的低精度的请求

PUT /museums
{
    "mappings": {
          "properties": {
              "location": {
                  "type": "geo_point"
              }
          }
    }
}

POST /museums/_bulk?refresh
{"index":{"_id":1}}
{"location": "52.374081,4.912350", "name": "NEMO Science Museum"}
{"index":{"_id":2}}
{"location": "52.369219,4.901618", "name": "Museum Het Rembrandthuis"}
{"index":{"_id":3}}
{"location": "52.371667,4.914722", "name": "Nederlands Scheepvaartmuseum"}
{"index":{"_id":4}}
{"location": "51.222900,4.405200", "name": "Letterenhuis"}
{"index":{"_id":5}}
{"location": "48.861111,2.336389", "name": "Musée du Louvre"}
{"index":{"_id":6}}
{"location": "48.860000,2.327000", "name": "Musée d'Orsay"}

POST /museums/_search?size=0
{
    "aggregations" : {
        "large-grid" : {
            "geohash_grid" : {
                "field" : "location",
                "precision" : 3
            }
        }
    }
}

响应:

{
    ...
    "aggregations": {
        "large-grid": {
            "buckets": [
                {
                    "key": "u17",
                    "doc_count": 3
                },
                {
                    "key": "u09",
                    "doc_count": 2
                },
                {
                    "key": "u15",
                    "doc_count": 1
                }
            ]
        }
    }
}

高精度的请求

当请求详细的桶(通常用于显示“放大”的地图)时,应应用类似geo_bounding_box的过滤器来缩小主题区域,否则可能会创建并返回数百万个桶。

POST /museums/_search?size=0
{
    "aggregations" : {
        "zoomed-in" : {
            "filter" : {
                "geo_bounding_box" : {
                    "location" : {
                        "top_left" : "52.4, 4.9",
                        "bottom_right" : "52.3, 5.0"
                    }
                }
            },
            "aggregations":{
                "zoom1":{
                    "geohash_grid" : {
                        "field": "location",
                        "precision": 8
                    }
                }
            }
        }
    }
}

geohash_grid 聚合返回的 geohash 也可用于放大。 要放大上例中返回的第一个geohash u17,应将它指定为top_leftbottom_right

POST /museums/_search?size=0
{
    "aggregations" : {
        "zoomed-in" : {
            "filter" : {
                "geo_bounding_box" : {
                    "location" : {
                        "top_left" : "u17",
                        "bottom_right" : "u17"
                    }
                }
            },
            "aggregations":{
                "zoom1":{
                    "geohash_grid" : {
                        "field": "location",
                        "precision": 8
                    }
                }
            }
        }
    }
}
{
    ...
    "aggregations" : {
        "zoomed-in" : {
            "doc_count" : 3,
            "zoom1" : {
                "buckets" : [
                    {
                        "key" : "u173zy3j",
                        "doc_count" : 1
                    },
                    {
                        "key" : "u173zvfz",
                        "doc_count" : 1
                    },
                    {
                        "key" : "u173zt90",
                        "doc_count" : 1
                    }
                ]
            }
        }
    }
}

对于不支持 geohash 的系统上的“放大”操作,应该使用一个可用的 geohash 库将桶的键转换为边界框。 例如,对于 javascript,可以使用node-geohash库:

var geohash = require('ngeohash');

// bbox will contain [ 52.03125, 4.21875, 53.4375, 5.625 ]
//                   [   minlat,  minlon,  maxlat, maxlon]
var bbox = geohash.decode_bbox('u17');

带有附加边界框过滤的请求

geohash_grid 聚合支持一个可选的参数-bounds,该参数将所考虑的坐标点限制在所提供的边界内。 参数 bounds 接受 地理边界框(geo_bounding_box)查询中的所有有效的格式的边界的边界框。 此边界框可与在聚合前过滤坐标点的附加geo_bounding_box查询一起使用,也可单独使用。 它是一个独立的边界框,可以与聚合上下文中定义的任何其他geo_bounding_box查询相交、相等或不相交。

POST /museums/_search?size=0
{
    "aggregations" : {
        "tiles-in-bounds" : {
            "geohash_grid" : {
                "field" : "location",
                "precision" : 8,
                "bounds": {
                  "top_left" : "53.4375, 4.21875",
                  "bottom_right" : "52.03125, 5.625"
                }
            }
        }
    }
}
{
    ...
    "aggregations" : {
        "tiles-in-bounds" : {
           "buckets" : [
               {
                 "key" : "u173zy3j",
                 "doc_count" : 1
               },
               {
                 "key" : "u173zvfz",
                 "doc_count" : 1
               },
               {
                 "key" : "u173zt90",
                 "doc_count" : 1
               }
           ]
        }
    }
}

赤道上的单元格的空间大小

下表显示了 geohash 的各种字符串长度所覆盖的单元格的空间纬度的大小。 单元格的尺寸随纬度变化,因此该表适用于赤道上的最坏情况。

geohash值长度

区域(宽 x 高)

1

5,009.4km x 4,992.6km

2

1,252.3km x 624.1km

3

156.5km x 156km

4

39.1km x 19.5km

5

4.9km x 4.9km

6

1.2km x 609.4m

7

152.9m x 152.4m

8

38.2m x 19m

9

4.8m x 4.8m

10

1.2m x 59.5cm

11

14.9cm x 14.9cm

12

3.7cm x 1.9cm

选项

field

必要的。使用 GeoPoints 索引的字段的名称。

precision

可选。用于在结果中定义单元格/桶的 geohash 的字符串长度。默认值为 5。 精度可以用上面提到的整数精度等级来定义。 超出[1,12]范围的值将被拒绝。 或者,可以从“1km”、“10m”这样的距离度量来近似计算精度等级。 计算精度的等级,使得单元格不会超过所需精度的指定大小(对角线)。 当这会导致精度等级高于支持的12级时(例如距离小于5.6厘米),该值将被拒绝。

bounds

可选。用于过滤桶中的坐标点的边界框。

size

可选。要返回的 geohash 桶的最大数量(默认为10,000)。 当结果被裁剪(trim)时,基于桶包含的文档数量来区分桶的优先级。

shard_size

可选。为了对最终结果中返回的前几个单元格进行更精确的计数,该聚合默认从每个分片返回 max(10,(size x number-of-shards)) 个桶。 如果不希望采用这种启发式方法,则可以使用此参数覆盖每个分片所考虑的数字。