ES高级应用之地理坐标数据类型

500 阅读2分钟

地理坐标是用经纬度描述地球表面的一个点。地理坐标可以用来计算两个坐标点之间的距离,还可以判断一个坐标是否在一个区域中。ES中要显式声明对应字段数据类型为geo_point

//示例
PUT /company-locations
{
  "settings": {}, 
  "mappings": {
    "properties": {
      "name":{
        "type":"text"
      },
      "location":{
        "type": "geo_point"
      }
    }
  }
}

location字段被声明为geo_point 后,就可以索引包含经纬度信息的文档了。经纬度信息的形式可以是字符串数组对象

//字符串形式
PUT /company-locations/_doc/1
{
  "name":"NETEASE",
  "location":"40.715,74.011"
}

//对象形式
PUT /company-locations/_doc/2
{
  "name":"Sina",
  "location":{
    "lat":40.722,
    "lon":73.989
  }
}



//数组形式
PUT /company-locations/_doc/3
{
  "name":"Baidu",
  "location":[73.983,40.719]
}

注意:

  • 字符串形式是英文逗号分隔,如"lat,lon"
  • 对象形式显式命名为lat和lon
  • 数组形式表示为[lat,lon]

通过地理坐标点过滤

有四种地理坐标点相关的过滤器,可以用来选中或者排除文档

过滤器作用
geo_bounding_box找出落在指定矩阵形框中的点
geo_distance找出与指定位置在给定距离内的点,一个圆里面的所有点
geo_distance_range找出与指定点距离在给定最小距离和最大距离之间的点,一个环形里面的所有点
geo_polygon找出落在多边形中的点。这个过滤器使用代价很大。当你觉得自己需要使用它,最好先看看geo_shapes

geo_bounding_box查询

这是目前为止最有效的地理坐标过滤器了,因为它计算起来非常简单。你指定一个矩形的顶部、底部、左边界、右边界,然后过滤器只需判断坐标的经度是否在左右边界之间,纬度是否在上下边界之间。

//示例
GET /company-locations/_search
{
  "query": {
    "bool": {
      "must":{
        "match_all":{}
      },
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 40.73,
              "lon": 71.12
            },
            "bottom_right": {
              "lat": 40.01,
              "lon": 74.1
            }
          }
        }
      }
    }
  }
}

geo_bounding_box主要是通过左上角和右下角两个点来确定矩形的边框,用top_leftbottom_right表示

geo_distance

过滤仅包含与地理位置相距特定距离内匹配的文档,简单说就是在一个特定半径的一个圆内的所有文档。

//示例
GET /company-locations/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all":{}
      },
      "filter": {
        "geo_distance": {
          "distance": "100km",
          "location": {
            "lat": 40,
            "lon": 70
          }
        }
      }
    }
  }
}