Elasticsearch geo_point/geo_shape

何为坐标

我们的日常生活中时时刻刻都在应用坐标技术,比如酒店预订,可以搜索展示附近的酒店,再比如搜索附近的餐厅. 衣食住行,所有的一切都离不开坐标,es提供了基于地理坐标的搜索,并和我们的生活喜喜相关.
在这里插入图片描述

经度是平面上的位置,从本初子午线作为零点,左右分别是[0,-180]和[0,+180],纬度是上半球[0,90] 和下半球[0,-90], 所以一个经纬度点(x,y)在地球上位移确定了一个位置. x可想象成球面坐标从0点的偏移量,y表示上下位置的便宜量,见上图.

一.elasticsearch 的地理坐标坐标分两种

Elasticsearch支持两种类型的地理数据:

  • geo_point:是一个(lon,lat) 经度/纬度 点
  • geo_shape: 是对geo_point不足之处的拓展.支持点、线、圆、多边形、多多边形.
    很多初次接触的童鞋,不理解geo_shape. 想象一下,一个学校在地理坐标中怎么表示? geo_point只是一个点位,无法表示一片区域, 所以这个时候就需要可以表示区域的数据结构,这就是geo_shape,这里先说到这里,后面还有详解.

二.geo_point的搜索

先不说怎么搜索,先来聊聊这个point,点顾名思义就是一个经纬度点. 也就是我们的es中存储的每条数据有一个字段存储的是一个经纬度的点. 对于数据中的经纬度点,我们能想到的就是查询的时候提供一个范围,然后判断目标索引中数据的经纬度是否在我提供的范围内, 或者我提供一个点,然后查找目标索引中距离我提供的点在一定距离内. 事实上es确实也是这么做的, 下面是es提供的集中搜索方式:

2.1 geo_bounding_box (矩形查询)
查询经纬度落在指定矩形内的数据,在坐标数据中,一个矩形可以由两个点表示. 两个点做平行线即可,在市级地理坐标中,则表示的在地球上围成的矩形范围. 平面几何图如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021063020234345.png#pic_center)

下面摘自官网的例子:

//构造mappings
PUT /my_locations
{
   
   
  "mappings": {
   
   
    "properties": {
   
   
      "pin": {
   
   
        "properties": {
   
   
          "location": {
   
   
            "type": "geo_point" //指定location字段类型是经纬度点坐标.
          }
        }
      }
    }
  }
}
//放入一条数据
PUT /my_locations/_doc/1
{
   
   
  "pin": {
   
   
    "location": {
   
   
      "lat": 40.12,
      "lon": -71.34
    }
  }
}
//查询: 意思是找出索引my_locations 中经纬度点在指定的矩形范围内的数据
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
            }
          }
        }
      }
    }
  }
}
2.2 geo_distance (距离查询)

顾名思义,距离查询的意思是用户指定一个经纬度,然后指定一个距离.表示查询出目标索引中 距离我指定的点 在我指定的范围内的所有数据.
实际上就是以我指定的点为中心,其他的点距离中心点不超过我指定的距离,几何图如下(实际上就是以指定的点为圆心,距离为半径画出的圆,所有在圆内的点都是符合条件的数据):
在这里插入图片描述
官方案例如下:

//建立mapping映射
PUT /my_locations
{
   
   
  "mappings": {
   
   
    "properties": {
   
   
      "pin": {
   
   
        "properties": {
   
   
          "location": {
   
   
            "type": "geo_point"
          }
        }
      }
    }
  }
}
//插入一条数据
PUT /my_locations/_doc/1
{
   
   
  "pin": {
   
   
    "location": {
   
   
      "lat": 40.12,
      "lon": -71.34
    }
  }
}
//查询指定半径
GET /my_locations/_search
{
   
   
  "query": {
   
   
    "bool": {
   
   
      "must": {
   
   
        "match_all": {
   
   }
      },
      "filter": {
   
   
        "geo_distance": {
   
   
          "distance": "200km",//我指定的距离半径
          "pin.location": {
   
    //我指定的圆心坐标点
            "lat": 40,
            "lon": -70
          }
        }
      }
    }
  }
}
2.3 geo_polygon(范围查询)

顾名思义就是我们是顶一个范围,去查询目标索引中落在指定范围内的点,将符合查询条件的数据查出来,这个范围是由多个点组成的,几何意义上是一个任意的不规则的范围.
在这里插入图片描述
官网案例: 三种写法

//第一种写法
GET /_search
{
   
   
  "query": {
   
   
    "bool": {
   
   
      "must": {
   
   
        "match_all": {
   
   }
      },
      "filter": {
   
   
        "geo_polygon": {
   
   
          "person.location": {
   
   
            "points": [
              {
   
    "lat": 
<think>好的,我现在需要详细解释一下Elasticsearch中的geo_shape类型。首先,我得回忆一下自己之前学过的相关知识,确保准确无误。 首先,geo_shape是用来处理地理空间数据的,比如多边形、线、点这些形状。和geo_point的区别在于,geo_point只处理经纬度点,而geo_shape可以处理更复杂的形状。这可能涉及到空间关系,比如判断一个点是否在某个区域内,或者两个区域是否有交集。 接下来,数据类型方面,geo_shapeElasticsearch中是一种字段类型。用户定义映射时需要指定。例如,创建一个索引时,字段类型设置为geo_shape,可能还需要指定一些参数,比如精度或者使用的树结构,比如geohash或者quadtree。这里可能需要提到一些术语,比如prefix trees,比如Geohash是如何将地理数据编码成字符串的,quadtree又是如何分割空间的。 然后,关于空间关系,Elasticsearch支持哪些呢?比如INTERSECTS、DISJOINT、WITHIN、CONTAINS等。这些关系在查询时使用,比如查询某个形状与索引中的文档是否有交集。 索引和查询的过程需要解释。索引地理形状时,Elasticsearch会将其转换为相应的前缀树结构中的网格单元,这会影响查询的精度和性能。可能还需要提到一些参数,比如tree、precision、tree_levels等,这些参数如何影响索引的细节。 在查询时,用户需要使用geo_shape查询,指定形状的坐标和空间关系类型。例如,使用geo_shape查询来查找所有与某个多边形相交的文档。这里需要举一个具体的例子,比如定义一个多边形区域,然后构造查询语句,使用WKT(Well-Known Text)格式或者GeoJSON格式来表示形状。 另外,可能还要提到一些注意事项。比如性能问题,复杂的形状或者高精度的设置可能导致索引变大,查询变慢。还有精度和误差之间的权衡,如何调整参数来优化。同时,不同Elasticsearch版本之间可能有差异,需要确认支持的版本。 可能还需要比较一下geo_shapegeo_point的应用场景。例如,geo_point适合存储点数据,并进行距离计算或聚合,而geo_shape适合处理区域覆盖、形状相交等复杂空间关系。 最后,提供一些示例代码,比如如何创建映射,如何索引一个多边形,如何执行查询。这些示例需要确保语法正确,并且符合Elasticsearch的版本要求。例如,使用GeoJSON格式定义形状,或者在查询中使用envelope来指定一个矩形区域。 在整理这些信息时,要注意结构的清晰,分点说明,让用户能够逐步理解geo_shape的各个方面。同时,要检查是否有遗漏的重要点,比如支持的形状类型(点、线、多边形、多边形集合等),或者坐标系的注意事项(WGS84坐标系,经纬度顺序是经度在前,纬度在后)等。可能还要提到如何处理坐标数组,比如多边形需要闭合,即第一个点和最后一个点相同。 总结下来,需要涵盖定义、用途、数据类型结构、空间关系类型、索引和查询方法、参数配置、示例以及注意事项。确保每个部分都简明扼要,准确无误,并且用中文表达自然,不使用Markdown格式。</think>Elasticsearch 的 `geo_shape` 类型用于处理复杂地理空间数据(如多边形、线、点集合等),支持空间关系判断(如相交、包含等)。以下是详细说明: --- ### **1. 核心概念** - **与 geo_point 的区别** `geo_point` 仅存储单个经纬度点,适合坐标检索和距离计算; `geo_shape` 存储复杂形状(如区域边界),支持空间关系分析。 - **坐标系要求** 使用 **WGS-84** 坐标系(即标准 GPS 经纬度),坐标格式为 `[经度, 纬度]`。 --- ### **2. 数据结构** #### **索引映射定义** ```json PUT /my_index { "mappings": { "properties": { "location": { "type": "geo_shape", "tree": "quadtree", // 可选前缀树类型:quadtree 或 geohash "precision": "100m" // 控制精度,影响索引细节 } } } } ``` - **tree**: 空间索引算法(默认 `quadtree`)。 - **precision**: 精度越高,索引越细密,但资源消耗越大(如 `1km`、`10m`)。 --- ### **3. 支持的形状类型** - **Point**: 单点 `{ "type": "Point", "coordinates": [13.4, 52.5] }` - **LineString**: 线段 `{ "type": "LineString", "coordinates": [[13.4,52.5], [13.5,52.6]] }` - **Polygon**: 多边形(必须闭合) ```json { "type": "Polygon", "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ] } ``` - **MultiPolygon**: 多个多边形集合 - **Envelope**: 矩形(通过左上、右下两点定义) `{ "type": "envelope", "coordinates": [[100.0, 1.0], [101.0, 0.0]] }` --- ### **4. 空间关系查询** #### **主要关系类型** - **INTERSECTS** (默认): 形状有交集 - **DISJOINT**: 完全不相交 - **WITHIN**: 被目标形状包含 - **CONTAINS**: 包含目标形状 #### **查询示例** ```json GET /my_index/_search { "query": { "geo_shape": { "location": { "relation": "INTERSECTS", "shape": { "type": "Polygon", "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ] } } } } } ``` --- ### **5. 性能优化建议** - **精度调节**: 更高的 `precision` 提高准确性但增加计算量,需权衡场景需求。 - **简化形状**: 减少多边形顶点数量以降低复杂度。 - **预定义形状**: 对频繁查询的形状可预先存储,通过 `indexed_shape` 引用。 ```json "shape": { "indexed_shape": { "index": "shapes_library", "id": "berlin_boundary", "path": "location" } } ``` --- ### **6. 典型应用场景** - **地理围栏**: 判断设备点(`geo_point`)是否在某个区域内(`geo_shape`)。 - **区域叠加分析**: 查找与某规划区域相交的土地地块。 - **路径规划**: 分析道路(线)与禁行区域(多边形)的交叉情况。 --- ### **7. 注意事项** - **坐标顺序**: 始终为 `[经度, 纬度]`,写反会导致错误。 - **多边形闭合**: 首尾坐标点需相同。 - **版本兼容性**: 部分功能(如 `geo_shape` 查询语法)在较旧版本中可能不同。 - **性能监控**: 复杂查询可能影响集群性能,需结合 `_search/validate` 调试。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我先森

鼓励一个吧,哈哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值