Elasticsearch:Geo-grid query - Elastic Stack 8.3

Posted Elastic 中国社区官方博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch:Geo-grid query - Elastic Stack 8.3相关的知识,希望对你有一定的参考价值。

在我之前的文章 “开始使用 Elasticsearch (3)”,我展示了一些 Geo 查询的一些案例:

  • Geo distance 聚合
  • Geo bounds 聚合
  • Geo centroid 聚合
  • Geo tile 聚合

在今天的文章中,我将详述 Geo grid 查询。它用于匹配与 GeoGrid 聚合中的网格单元相交的 geo_pointgeo_shape 值。该查询旨在通过提供存储桶的键来匹配落在 geogrid 聚合存储桶内的文档。 对于 geohash 和 geotile 网格,查询可用于 geo_point 和 geo_shape 字段。 对于 geo_hex 网格,它只能用于 geo_point 字段。

例子

假设以下文档被索引:

PUT /my_locations

  "mappings": 
    "properties": 
      "location": 
        "type": "geo_point"
      
    
  


PUT /my_locations/_doc/1?refresh

  "location" : "POINT(4.912350 52.374081)",
  "city": "Amsterdam",
  "name": "NEMO Science Museum"


PUT /my_locations/_doc/2?refresh

  "location" : "POINT(4.405200 51.222900)",
  "city": "Antwerp",
  "name": "Letterenhuis"


PUT /my_locations/_doc/3?refresh

  "location" : "POINT(2.336389 48.861111)",
  "city": "Paris",
  "name": "Musée du Louvre"

上面的三个点可以在地图上表示如下:

geohash grid

可能有些开发者对于 geohash 还是不很了解。如果你想了解的话,请阅读我之前的文章 “Elasticsearch:理解 Elastic Maps 中的 geohash 及其聚合”。使用 geohash_grid 聚合,可以根据文档的 geohash 值对文档进行分组:

GET /my_locations/_search?filter_path=aggregations

  "size" : 0,
  "aggs" : 
     "grouped" : 
        "geohash_grid" : 
           "field" : "location",
           "precision" : 2
        
     
  

在上面,我们请求的精度为 2。上面返回的结果为:


  "aggregations": 
    "grouped": 
      "buckets": [
        
          "key": "u1",
          "doc_count": 2
        ,
        
          "key": "u0",
          "doc_count": 1
        
      ]
    
  

我们可以看出来数据被分成两个组。它们分别位于不同的 geohash 的网格中。

当然,我们也可以把精度设置为更低,比如:

GET /my_locations/_search?filter_path=aggregations

  "size" : 0,
  "aggs" : 
     "grouped" : 
        "geohash_grid" : 
           "field" : "location",
           "precision" : 1 
        
     
  

在上面,precision 为 1,那么上面搜索返回的结果为:


  "aggregations": 
    "grouped": 
      "buckets": [
        
          "key": "u",
          "doc_count": 3
        
      ]
    
  

Geohash 的网格是这样的:

当精度越低,那么它包含的地理面积就越大,这样极有可能把相近的地理位置点聚合到同一个网格中。从我们返回的数据中,我们可以看得出来 u0 及 u1 应该是在包含我们上面三个数据的网格里。它们处于 u 的网格中。

geotile grid 

有关 geotile grid 的聚合,我有在之前的文章  “开始使用 Elasticsearch (3)” 中有详述。使用 geotile_grid 聚合,可以根据其 geotile 值对文档进行分组:

GET /my_locations/_search?filter_path=aggregations

  "size" : 0,
  "aggs" : 
     "grouped" : 
        "geotile_grid" : 
           "field" : "location",
           "precision" : 6
        
     
  

上面的命令返回的结果为:


  "aggregations": 
    "grouped": 
      "buckets": [
        
          "key": "6/32/21",
          "doc_count": 2
        ,
        
          "key": "6/32/22",
          "doc_count": 1
        
      ]
    
  

我们可以根据返回的数据的 key 值来显示该桶所在位置的 png 文件:

 从上面,我们可以看出来,它包含 Amsterdam 及 Antwerp 两个位置,而另外一幅图则包含 Paris:

 使用 geotile_grid 聚合,可以根据其 geotile 值对文档进行分组:

GET /my_locations/_search?filter_path=**.hits

  "query": 
    "geo_grid" :
      "location" : 
        "geotile" : "6/32/22"
      
    
  

上面是使用上面返回的 geotile 值 6/32/22 来进行查询的。我可以通过它来确定到底是那个一个文档匹配:


  "hits": 
    "hits": [
      
        "_index": "my_locations",
        "_id": "3",
        "_score": 1,
        "_source": 
          "location": "POINT(2.336389 48.861111)",
          "city": "Paris",
          "name": "Musée du Louvre"
        
      
    ]
  

显然它对应于 Paris 这个位置。

geohex grid

使用 geohex_grid 聚合,可以根据其 geohex 值对文档进行分组。特别值得指出的是,geo-hex-agg 是一个需要版权才可以实现的功能。我们需要启动白金版试用功能:

我们再次执行上面的聚合:

GET /my_locations/_search?filter_path=aggregations

  "size" : 0,
  "aggs" : 
     "grouped" : 
        "geohex_grid" : 
           "field" : "location",
           "precision" : 1
        
     
  

上面聚合的结果为:


  "aggregations": 
    "grouped": 
      "buckets": [
        
          "key": "81197ffffffffff",
          "doc_count": 2
        ,
        
          "key": "811fbffffffffff",
          "doc_count": 1
        
      ]
    
  

我们可以通过使用具有以下语法的存储桶键执行 geo_grid 查询来提取其中一个存储桶上的文档:

GET /my_locations/_search?filter_path=**.hits

  "query": 
    "geo_grid" :
      "location" : 
        "geohex" : "811fbffffffffff"
      
    
  

上面的命令返回的结果为:


  "hits": 
    "hits": [
      
        "_index": "my_locations",
        "_id": "3",
        "_score": 1,
        "_source": 
          "location": "POINT(2.336389 48.861111)",
          "city": "Paris",
          "name": "Musée du Louvre"
        
      
    ]
  

从上面,我们可以看出来 Paris 这个位置处于 geohex 值为 811fbffffffffff 的网格中。

以上是关于Elasticsearch:Geo-grid query - Elastic Stack 8.3的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch 可以流式传输 SearchResponse 吗?

史上最全面的Elasticsearch使用指南

Elasticsearch系列---定制mapping

Elasticsearch深入7

elasticSearch - 高级检索

Elasticsearch系列---近似匹配