• 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 字段。

    例子

    假设以下文档被索引:

    1. PUT /my_locations
    2. {
    3. "mappings": {
    4. "properties": {
    5. "location": {
    6. "type": "geo_point"
    7. }
    8. }
    9. }
    10. }
    11. PUT /my_locations/_doc/1?refresh
    12. {
    13. "location" : "POINT(4.912350 52.374081)",
    14. "city": "Amsterdam",
    15. "name": "NEMO Science Museum"
    16. }
    17. PUT /my_locations/_doc/2?refresh
    18. {
    19. "location" : "POINT(4.405200 51.222900)",
    20. "city": "Antwerp",
    21. "name": "Letterenhuis"
    22. }
    23. PUT /my_locations/_doc/3?refresh
    24. {
    25. "location" : "POINT(2.336389 48.861111)",
    26. "city": "Paris",
    27. "name": "Musée du Louvre"
    28. }

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

    geohash grid

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

    1. GET /my_locations/_search?filter_path=aggregations
    2. {
    3. "size" : 0,
    4. "aggs" : {
    5. "grouped" : {
    6. "geohash_grid" : {
    7. "field" : "location",
    8. "precision" : 2
    9. }
    10. }
    11. }
    12. }

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

    1. {
    2. "aggregations": {
    3. "grouped": {
    4. "buckets": [
    5. {
    6. "key": "u1",
    7. "doc_count": 2
    8. },
    9. {
    10. "key": "u0",
    11. "doc_count": 1
    12. }
    13. ]
    14. }
    15. }
    16. }

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

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

    1. GET /my_locations/_search?filter_path=aggregations
    2. {
    3. "size" : 0,
    4. "aggs" : {
    5. "grouped" : {
    6. "geohash_grid" : {
    7. "field" : "location",
    8. "precision" : 1
    9. }
    10. }
    11. }
    12. }

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

    1. {
    2. "aggregations": {
    3. "grouped": {
    4. "buckets": [
    5. {
    6. "key": "u",
    7. "doc_count": 3
    8. }
    9. ]
    10. }
    11. }
    12. }

    Geohash 的网格是这样的:

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

    geotile grid 

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

    1. GET /my_locations/_search?filter_path=aggregations
    2. {
    3. "size" : 0,
    4. "aggs" : {
    5. "grouped" : {
    6. "geotile_grid" : {
    7. "field" : "location",
    8. "precision" : 6
    9. }
    10. }
    11. }
    12. }

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

    1. {
    2. "aggregations": {
    3. "grouped": {
    4. "buckets": [
    5. {
    6. "key": "6/32/21",
    7. "doc_count": 2
    8. },
    9. {
    10. "key": "6/32/22",
    11. "doc_count": 1
    12. }
    13. ]
    14. }
    15. }
    16. }

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

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

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

    1. GET /my_locations/_search?filter_path=**.hits
    2. {
    3. "query": {
    4. "geo_grid" :{
    5. "location" : {
    6. "geotile" : "6/32/22"
    7. }
    8. }
    9. }
    10. }

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

    1. {
    2. "hits": {
    3. "hits": [
    4. {
    5. "_index": "my_locations",
    6. "_id": "3",
    7. "_score": 1,
    8. "_source": {
    9. "location": "POINT(2.336389 48.861111)",
    10. "city": "Paris",
    11. "name": "Musée du Louvre"
    12. }
    13. }
    14. ]
    15. }
    16. }

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

    geohex grid

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

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

    1. GET /my_locations/_search?filter_path=aggregations
    2. {
    3. "size" : 0,
    4. "aggs" : {
    5. "grouped" : {
    6. "geohex_grid" : {
    7. "field" : "location",
    8. "precision" : 1
    9. }
    10. }
    11. }
    12. }

    上面聚合的结果为:

    1. {
    2. "aggregations": {
    3. "grouped": {
    4. "buckets": [
    5. {
    6. "key": "81197ffffffffff",
    7. "doc_count": 2
    8. },
    9. {
    10. "key": "811fbffffffffff",
    11. "doc_count": 1
    12. }
    13. ]
    14. }
    15. }
    16. }

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

    1. GET /my_locations/_search?filter_path=**.hits
    2. {
    3. "query": {
    4. "geo_grid" :{
    5. "location" : {
    6. "geohex" : "811fbffffffffff"
    7. }
    8. }
    9. }
    10. }

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

    1. {
    2. "hits": {
    3. "hits": [
    4. {
    5. "_index": "my_locations",
    6. "_id": "3",
    7. "_score": 1,
    8. "_source": {
    9. "location": "POINT(2.336389 48.861111)",
    10. "city": "Paris",
    11. "name": "Musée du Louvre"
    12. }
    13. }
    14. ]
    15. }
    16. }

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

  • 相关阅读:
    刷题日记【第十三篇】-笔试必刷题【数根+星际密码+跳台阶扩展问题+快到碗里来】
    刷题笔记之七(统计每个月兔子的总数+汽水瓶+查找两个字符串a,b中的最长公共子串+公共子串计算)
    云计算-桌面云-国产-华为-FusionAccess+HCIE Cloud相关知识点+笔试题库
    2022.7.30 C++——final和override关键字
    态路小课堂丨400G QSFP112—助力IDC数据中心升级
    【SQL】索引失效的11种情况
    测试开发概念篇
    linux内核源码分析之物理内存
    获得淘宝商品快递费用接口调用展示
    RPA可以为你完成哪些重复性工作?
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/126223102