参考官网 Elasticsearch Reference [7.10] » Query DSL » Geo queries

一、准备数据

1.1、geo_point

  ES中特有的类型geo_point,用来存储地图类型,某平台外卖。快递体现的配送人员距离你多少米,就是这个数据类型做出来的。

1.2、新建索引map

PUT /map
{
  "settings": {
    "number_of_replicas": 3,
    "number_of_shards": 5
  }
  , "mappings": {
    "properties": {
      "name":
      {
        "type": "text"
      }
      ,"location":
      {
        "type": "geo_point"
      }
    }
  }
}

1.3、添加数据

PUT /map/_doc/1
{
  "name":"天安门",
  "location":
  {
    "lon":116.403981,
    "lat":39.914492
  }
}


PUT /map/_doc/2
{
  "name":"海淀公园",
  "location":
  {
    "lon":116.302509,
    "lat":39.991152
  }
}

PUT /map/_doc/3
{
  "name":"北京动物园",
  "location":
  {
    "lon":116.343184,
    "lat":39.947468
  }
}

二、ES的地图检索方式

ES支持的地图检索方式有以下几种;

  • geo_distance
  • geo_bounding_box
  • geo_polygon

2.1、geo_distance:直线距离检索,如给定点A,要求返回地图上距离点A三千米的商家(点外卖场景)

在这里插入图片描述

2.1.1、查找索引内距离北京站(116.433733,39.908404)3000米内的点

geo_distance涉及的参数如下

  • location:确定一个点;
  • distance:确定一个半径,单位米
  • distance_type:确定一个图形的类型,一般是圆形,arc
2.1.1.1、Restful 代码
POST /map/_search
{
  "query": {
    "geo_distance":
    {
      "location":
      {
        "lon":116.433733
        ,"lat":39.908404
      },
      "distance":3000,
      "distance_type":"arc"
    }

  }
}

在这里插入图片描述

2.1.1.2、java 代码实现
package com.chb.test;

import com.chb.utils.ESClient;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;

import java.io.IOException;

public class GeoDemo {
    RestHighLevelClient client = ESClient.getClient();
    String index = "map";

    @Test
    public void geoDistance() throws IOException {
        // 1、SearchRequest对象
        SearchRequest searchRequest = new SearchRequest(index);

        // 2、指定查询参数
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.geoDistanceQuery("location").distance("3000").point(39.908404,116.433733));
        // 将条件添加到request对象
        searchRequest.source(searchSourceBuilder);

        // 3、执行
        SearchResponse resp = client.search(searchRequest, RequestOptions.DEFAULT);

        // 4、输出
        for (SearchHit hit : resp.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }

    }

}

2.2、geo_bounding_box:以两个点确定一个矩形,获取在矩形内的全部数据

在这里插入图片描述

2.2.1、geo_bounding_box涉及的参数如下

  • top_left: 左上角的矩形起始点经纬度;
  • bottom_right: 右下角的矩形结束点经纬度

2.2.2、查找索引内位于中央民族大学(116.326943,39.95499)以及京站(116.433733,39.908404)矩形的点

2.2.2.1、RESTful 代码
POST /map/_search
{
  "query": {
    "geo_bounding_box": {
      "location": {
        "top_left": {
          "lon": 116.326943,
          "lat": 39.95499
        },
        "bottom_right": {
          "lon": 116.433446,
          "lat": 39.908737
        }
      }
    }
  }
}

在这里插入图片描述

2.2.2.2、java 代码
        // 2、指定查询参数
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // =======改变的代码========
        searchSourceBuilder.query(QueryBuilders.geoBoundingBoxQuery("location").setCorners(39.95499,116.326943,39.908737,116.433446));
        // =====================
        // 将条件添加到request对象
        searchRequest.source(searchSourceBuilder);

2.3、geo_polygon:以多个点,确定多边形,获取多边形内的全部数据

在这里插入图片描述

2.3.1、geo_polygon涉及的参数如下

points:是个数组,存储多变形定点的经纬度,每个点用大括号包起来

2.3.2、查找索引内位于西苑桥(116.300209,40.003423),巴沟山水园(116.29561,39.976004)以及北京科技大学(116.364528,39.996348)三角形内的点

2.3.2.1、RESTful 代码
POST /map/_search
{
  "query": {
    "geo_polygon": {
      "location": {
        "points": [
          {
            "lon": 116.29561,
            "lat": 39.976004
          },
          {
            "lon": 116.364528,
            "lat": 39.996348
          },
          {
            "lon": 116.300209,
            "lat": 40.003423
          }
        ]
      }
    }
  }
}

在这里插入图片描述

2.3.2.2、java 代码
        // 2、指定查询参数
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // =======改变的代码========
        List<GeoPoint> points=new ArrayList<GeoPoint>();
        //注意java里面是纬经度的顺序,不要搞反了
        points.add(new GeoPoint(39.976004,116.29561));
        points.add(new GeoPoint(39.996348,116.364528));
        points.add(new GeoPoint(40.003423,116.300209));
        searchSourceBuilder.query(QueryBuilders.geoPolygonQuery("location", points));
        // =====================
        // 将条件添加到request对象
        searchRequest.source(searchSourceBuilder);

关注我的公众号【宝哥大数据】,更多干货

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐