ElasticSearch查询学习笔记章节5——geo_distance,geo_bounding_box,geo_polygon地图检索geo查询

ElasticSearch查询笔记目录

  涉及的常用查询内容较多,将分多个章节进行笔记整理,具体如下:

  1. ElasticSearch查询学习笔记章节1——term,terms,match,id查询

   主要是依据精准的查询条件来查询,查询速度快,也是最常用的几类查询方式,具体种类如下:

  • term查询
  • terms查询
  • match_all查询
  • match查询
  • 布尔match查询
  • multi_match查询
  • 根据文档id查询(单个id)
  • 根据文档ids查询(多个id)
  1. ElasticSearch查询学习笔记章节2——prefix,fuzzy,wildcard,range,regexp查询

  主要是涉及ElasticSearch查询条件相对模糊,查询速度相对慢,实时查询时应尽量避免这些方式,但是这些查询方式又具有自己独特不可代替的功能,还是还有必要,具体如下:

  • prefix查询
  • fuzzy查询
  • wildcard查询
  • range查询
  • regexp查询
  1. ElasticSearch查询学习笔记章节3——scroll,delete-by-query,bool,boosting,filter,highlight查询**

  主要涉及ElasticSearch的一些常用的杂项查询;

  • 深分页scroll查询
  • delete-by-query
  • bool查询
  • boosting查询
  • filter查询
  • highlight(高亮)查询
  1. ElasticSearch查询学习笔记章节4——cardinality,range,extended_stats聚合统计aggregations查询

  主要涉及ES的聚合查询Aggregations;

  • cardinality(去重计数)查询
  • range(范围统计)查询
  • extended_stats(统计聚合)查询
  1. ElasticSearch查询学习笔记章节5——geo_distance,geo_bounding_box,geo_polygon地图检索geo查询

.   主要涉及ES的地图检索geo相关的查询;

  • geo_distance查询
  • geo_bounding_box查询
  • geo_polygon查询

整体Java代码的测试用例项目

  整个章节的Java代码放在CSDN资源ElasticSearch常用查询的Java实现;路径效果如下图,欢迎下载访问;在这里插入图片描述

geo_point索引、数据准备

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

新建索引map

  RESTFul风格的创建索引my_badu_map如下;

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

  RESTFul风格给索引my_badu_map添加数据;

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


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

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

  RESTFul风格预览数据如下;

POST /my_badu_map/_search

#数据结果如下
{
  "took" : 815,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "北京动物园",
          "location" : {
            "lon" : 116.343184,
            "lat" : 39.947468
          }
        }
      },
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "海淀公园",
          "location" : {
            "lon" : 116.302509,
            "lat" : 39.991152
          }
        }
      },
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "天安门",
          "location" : {
            "lon" : 116.403981,
            "lat" : 39.914492
          }
        }
      }
    ]
  }
}

ES的地图检索方式

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

  • geo_distance:直线距离检索,如给定点A,要求返回地图上距离点A三千米的商家(点外卖场景),如图1;
  • 在这里插入图片描述
图1 geo_distance场景
  • geo_bounding_box:以两个点确定一个矩形,获取在矩形内的全部数据,如图2;
    在这里插入图片描述
图2 geo_bounding_box场景
  • geo_polygon:以多个点,确定多边形,获取多边形内的全部数据,如图3;

在这里插入图片描述

图3 geo_polygon场景

基于RESTFul风格实现地图检索

geo_distance

geo_distance涉及的参数如下
location:确定一个点;
distance:确定一个半径,单位米
distance_type:确定一个图形的类型,一般是圆形,arc

  实现要求,查找索引内距离北京站(116.433733,39.908404)3000米内的点;

  RESTFUL代码如下;

POST /my_badu_map/_search
{
  "query": {
    "geo_distance":
    {
      "location":
      {
        "lon":116.433733
        ,"lat":39.908404
      },
      "distance":3000,
      "distance_type":"arc"
    }

  }
}

  RESTFUL代码效果如下,在3千米内,是包含了北京天安门的;

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "天安门",
          "location" : {
            "lon" : 116.403981,
            "lat" : 39.914492
          }
        }
      }
    ]
  }
}

geo_bounding_box

geo_bounding_box涉及的参数如下
top_left:左上角的矩形起始点经纬度;
bottom_right右下角的矩形结束点经纬度

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

  RESTFUL代码如下;

POST /my_badu_map/_search
{
  "query": {
    "geo_bounding_box":
    {
      "location":
      {
        "top_left":
        {
          "lon":116.326943,
          "lat":39.95499
        }
        ,"bottom_right":
        {
          "lon":116.433446,
          "lat":39.908737
        }
      }
    }
  }
}

  RESTFUL代码效果如下,北京动物园和天安门在中央民族大学(116.326943,39.95499)以及京站(116.433733,39.908404)矩形内;

{
  "took" : 37,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "北京动物园",
          "location" : {
            "lon" : 116.343184,
            "lat" : 39.947468
          }
        }
      },
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "天安门",
          "location" : {
            "lon" : 116.403981,
            "lat" : 39.914492
          }
        }
      }
    ]
  }
}

geo_polygon

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

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

  RESTFUL代码如下;

POST /my_badu_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
          }
          
        ]
      }
    }
  }
}

  RESTFUL代码效果如下,海淀公园位于西苑桥(116.300209,40.003423),巴沟山水园(116.29561,39.976004)以及北京科技大学(116.364528,39.996348)三角形内;

{
  "took" : 204,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_badu_map",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "海淀公园",
          "location" : {
            "lon" : 116.302509,
            "lat" : 39.991152
          }
        }
      }
    ]
  }
}

基于Java代码实现地图检索

geo_distance

geo_distance涉及的参数如下
location:确定一个点;
distance:确定一个半径,单位米
distance_type:确定一个图形的类型,一般是圆形,arc

  实现要求,查找索引内距离北京站(116.433733,39.908404)3000米内的点;

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";
    String index2="my_badu_map";

    @Test
    public void geoDistance() throws IOException {
        //1.SearchRequest
        SearchRequest request=new SearchRequest(index2);

        //2.指定检索方式
        SearchSourceBuilder builder=new SearchSourceBuilder();  
        builder.query(QueryBuilders.geoDistanceQuery("location").distance("3000").point(39.908404,116.433733));
        request.source(builder);

        //3.执行查询
        SearchResponse resp = myClient.search(request, RequestOptions.DEFAULT);

        //4.返回结果
        for (SearchHit hit : resp.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

  Java代码实现geo_distance如下图4;
在这里插入图片描述

图4 Java实现geo_polygon的效果

geo_bounding_box

geo_bounding_box涉及的参数如下
top_left:左上角的矩形起始点经纬度;
bottom_right右下角的矩形结束点经纬度

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

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";
    String index2="my_badu_map";

    @Test
    public void geoBoundingBox() throws IOException {
        //1.SearchRequest
        SearchRequest request=new SearchRequest(index2);

        //2.指定检索方式
        SearchSourceBuilder builder=new SearchSourceBuilder();
        builder.query(QueryBuilders.geoBoundingBoxQuery("location").setCorners(39.95499,116.326943,39.908737,116.433446));
        request.source(builder);

        //3.执行查询
        SearchResponse resp = myClient.search(request, RequestOptions.DEFAULT);

        //4.返回结果
        for (SearchHit hit : resp.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    Java实现geo_bounding_box的效果如图5;

在这里插入图片描述

图5 Java实现geo_bounding_box的效果

geo_polygon

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

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

  Java实现代码代码如下;

   static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";
    String index2="my_badu_map";

    @Test
    public void geoPolygon() throws IOException {
        //1.SearchRequest
        SearchRequest request=new SearchRequest(index2);

        //2.指定检索方式
        SearchSourceBuilder builder=new SearchSourceBuilder();
        List<GeoPoint> points=new ArrayList<>();
        //注意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));
        builder.query(QueryBuilders.geoPolygonQuery("location",points));

        request.source(builder);

        //3.执行查询
        SearchResponse resp = myClient.search(request, RequestOptions.DEFAULT);

        //4.返回结果
        for (SearchHit hit : resp.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }


  Java实现geo_polygon的效果如图6;

在这里插入图片描述

图6 Java实现geo_polygon的效果

  更多的geo地图检索,可以参考官网geo-queries;

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

╭⌒若隐_RowYet——大数据

谢谢小哥哥,小姐姐的巨款

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

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

打赏作者

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

抵扣说明:

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

余额充值