• Elasticsearch:Geoshape query - 过滤含有地理位置的文档


    Geoshape query 是用来过滤含有 geo_shape 或者 geo_point 类型的文档。在使用这个查询之前,你需要在你的索引 mapping 中显式地定义它们的数据类型,比如:

    1. PUT /example
    2. {
    3. "mappings": {
    4. "properties": {
    5. "location": {
    6. "type": "geo_shape"
    7. }
    8. }
    9. }
    10. }

    在上面,我们定义 location 的数据类型为 geo_shape。

    1. PUT my-index-000001
    2. {
    3. "mappings": {
    4. "properties": {
    5. "location": {
    6. "type": "geo_point"
    7. }
    8. }
    9. }
    10. }

    在上面,我们定义 location 的数据类型为 geo_point。

    geo_shape 查询使用与 geo_shape 映射相同的方格表示来查找具有与查询形状相关的形状的文档,使用指定的空间关系:相交、包含、在内部或不相交。 它还将使用为字段映射定义的相同前缀树配置。

    查询支持两种定义查询形状的方法,一种是提供完整的形状定义,另一种是引用在另一个索引中预索引的形状的名称。 下面通过示例定义了这两种格式。

    内置形状定义

    与 geo_point 类型类似,geo_shape 查询使用 GeoJSON 来表示形状。

    给定以下索引,位置为 geo_shape 字段:

    1. PUT /example
    2. {
    3. "mappings": {
    4. "properties": {
    5. "location": {
    6. "type": "geo_shape"
    7. }
    8. }
    9. }
    10. }
    11. POST /example/_doc?refresh
    12. {
    13. "name": "Wind & Wetter, Berlin, Germany",
    14. "location": {
    15. "type": "point",
    16. "coordinates": [ 13.400544, 52.530286 ]
    17. }
    18. }

    以下查询将使用 Elasticsearch 的信封(envelope) GeoJSON 扩展找到该点:

    1. GET /example/_search?filter_path=**.hits
    2. {
    3. "query": {
    4. "bool": {
    5. "must": {
    6. "match_all": {}
    7. },
    8. "filter": {
    9. "geo_shape": {
    10. "location": {
    11. "shape": {
    12. "type": "envelope",
    13. "coordinates": [ [ 13.0, 53.0 ], [ 14.0, 52.0 ] ]
    14. },
    15. "relation": "within"
    16. }
    17. }
    18. }
    19. }
    20. }
    21. }

    上面搜索的结果为:

    1. {
    2. "hits": {
    3. "hits": [
    4. {
    5. "_index": "example",
    6. "_id": "N6ikhYIBT1laGVGsUcSa",
    7. "_score": 1,
    8. "_source": {
    9. "name": "Wind & Wetter, Berlin, Germany",
    10. "location": {
    11. "type": "point",
    12. "coordinates": [
    13. 13.400544,
    14. 52.530286
    15. ]
    16. }
    17. }
    18. }
    19. ]
    20. }
    21. }

    这个,我们可以从地图上进行显示:

    很显然,坐标位置为 [ 13.400544, 52.530286 ] 的点处于上面的矩形框里。它能够被正确地搜索到。

    类似地,可以在 geo_point 字段上查询上述查询。

    1. PUT /example_points
    2. {
    3. "mappings": {
    4. "properties": {
    5. "location": {
    6. "type": "geo_point"
    7. }
    8. }
    9. }
    10. }
    11. PUT /example_points/_doc/1?refresh
    12. {
    13. "name": "Wind & Wetter, Berlin, Germany",
    14. "location": [13.400544, 52.530286]
    15. }

    使用相同的查询,返回具有匹配 geo_point 字段的文档。

    1. GET /example_points/_search?filter_path=**.hits
    2. {
    3. "query": {
    4. "bool": {
    5. "must": {
    6. "match_all": {}
    7. },
    8. "filter": {
    9. "geo_shape": {
    10. "location": {
    11. "shape": {
    12. "type": "envelope",
    13. "coordinates": [ [ 13.0, 53.0 ], [ 14.0, 52.0 ] ]
    14. },
    15. "relation": "intersects"
    16. }
    17. }
    18. }
    19. }
    20. }
    21. }

    上面查询的结果为:

    1. {
    2. "hits": {
    3. "hits": [
    4. {
    5. "_index": "example_points",
    6. "_id": "1",
    7. "_score": 1,
    8. "_source": {
    9. "name": "Wind & Wetter, Berlin, Germany",
    10. "location": [
    11. 13.400544,
    12. 52.530286
    13. ]
    14. }
    15. }
    16. ]
    17. }
    18. }

    预索引形状

    该查询还支持使用已在另一个索引中建立索引的形状。 当你有一个预定义的形状列表并且你希望使用逻辑名称(例如新西兰)而不是每次都提供坐标来引用该列表时,这特别有用。 在这种情况下,只需提供:

    • id - 包含预索引形状的文档的 ID。
    • index - 预索引形状所在的索引名称。 默认为 shapes。
    • path - 指定为包含预索引形状的路径的字段。 默认为 shape。
    • routing - 如果需要,形状文档的路由。

    以下是使用带有预索引形状的过滤器的示例:

    1. PUT /shapes
    2. {
    3. "mappings": {
    4. "properties": {
    5. "location": {
    6. "type": "geo_shape"
    7. }
    8. }
    9. }
    10. }
    11. PUT /shapes/_doc/deu
    12. {
    13. "location": {
    14. "type": "envelope",
    15. "coordinates" : [[13.0, 53.0], [14.0, 52.0]]
    16. }
    17. }

    在上面,我们创建了一个叫做 shapes 的索引。我们为它创建了一个 id 为 deu 的文档。它的显示区域就是上面地图中的黄色部分。我们接下来使用如下的搜索:

    1. GET /example/_search
    2. {
    3. "query": {
    4. "bool": {
    5. "filter": {
    6. "geo_shape": {
    7. "location": {
    8. "indexed_shape": {
    9. "index": "shapes",
    10. "id": "deu",
    11. "path": "location"
    12. }
    13. }
    14. }
    15. }
    16. }
    17. }
    18. }

    搜索的结果和之前的是一样的。只不过现在的 envelope 是定义在另外一个索引中,而不是之前在查询的语句中定义的。这样的做法在实际的使用中有很多意义,比如我可以使用一个索引定义需要经常查询的区域。我们在使用时,可以针对这些区域分别进行查询。我们无需每次查询时在查询语句中定义区域,取而代之的是一个比较有意义的 id 名称。这样使用更加人性化一些。

    空间关系

    以下是搜索地理字段时可用的空间关系运算符的完整列表:

    • INTERSECTS -(默认)返​​回其 geo_shape 或 geo_point 字段与查询几何相交的所有文档。
    • DISJOINT - 返回其 geo_shape 或 geo_point 字段与查询几何没有任何共同点的所有文档。
    • WITHIN - 返回其 geo_shape 或 geo_point 字段在查询几何范围内的所有文档。不支持线几何。
    • CONTAINS - 返回其 geo_shape 或 geo_point 字段包含查询几何的所有文档。

    ignore unmapped
    当设置为 true 时,ignore_unmapped 选项将忽略未映射的字段,并且不会匹配此查询的任何文档。这在查询可能具有不同映射的多个索引时很有用。当设置为 false(默认值)时,如果字段未映射,查询将引发异常。

    注意:当数据在 geo_shape 字段中作为形状数组被索引时,这些数组被视为一个形状。因此,以下请求是等效的。

    1. PUT /test/_doc/1
    2. {
    3. "location": [
    4. {
    5. "coordinates": [46.25,20.14],
    6. "type": "point"
    7. },
    8. {
    9. "coordinates": [47.49,19.04],
    10. "type": "point"
    11. }
    12. ]
    13. }

    上面的请求和下面的请求是一样的:

    1. PUT /test/_doc/1
    2. {
    3. "location":
    4. {
    5. "coordinates": [[46.25,20.14],[47.49,19.04]],
    6. "type": "multipoint"
    7. }
    8. }

    geo_shape 查询假定 geo_shape 字段使用 RIGHT(逆时针)的默认方向。多边形的方向指示其顶点的顺序:RIGHT(逆时针)或 LEFT(顺时针)。 Elasticsearch 使用多边形的方向来确定它是否穿过国际日期变更线(+/-180° 经度)。

  • 相关阅读:
    聊聊ChatGLM6B的微调脚本及与Huggingface的关联
    C语言--每日五道选择题--Day3
    设计模式之代理模式与外观模式
    windows系统使用Vscode在WSL调试golang本地进程
    CKA认证,开启您的云原生之旅!
    设计资讯 | 迷你PC:配备 Ryzen 9 芯片组和 7 英寸触摸屏,与 Mac Studio 大小相当
    实现一个小功能,原生js点击图片上传图片并切换
    SqlPlus访问oracle
    RabbitMQ中VirtualHost相关设置、SpringBoot中集成常见问题总结
    FFmpeg进阶:音视频滤镜概述
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/126261566