• Elasticsearch 基于地理位置的搜索查询


             ES为用户提供了基于地理位置的搜索功能。它主要支持两种类型的地理查询:一种是地理点(geo_point),即经纬度查询,另一种是地理形状查询(geo_shape),即支持点,线,圆形和多边形等查询。

            从实用性来说,地理点(即geo_point)数据类型的使用更多一些,对于geo_point字段类型的查询方式有三种,分别为geo_distance查询(圆形区域查询),geo_bounding_box查询(矩形区域查询)和geo_polygon查询(多边形区域查询)。

    1.geo_distance圆形区域查询

    geo_distance需要指定一个坐标点,在指定该点距离的范围后,ES可查询到以该点为中心,距离为半径的圆形区域的数据。

    1.1 查询的DSL

    1. GET index_school/_search
    2. {
    3. "_source": [ // 只返回部分字段
    4. "name",
    5. "latitude",
    6. "longitude",
    7. "devideNo",
    8. "time"
    9. ],
    10. "query": {
    11. "geo_distance":{
    12. "distance": "5km", // 距离范围(半径)为5km
    13. "location":{ //中心点经纬度
    14. "lat": "18.231472",
    15. "lon": "109.502083"
    16. }
    17. }
    18. }
    19. }

    1.2 java实现

    1. SearchRequest request = new SearchRequest(tableName);
    2. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    3. boolQuery.filter(QueryBuilders.geoDistanceQuery("location") //指定索引字段
    4. .distance(inputDTO.getDistance()) //距离中心点范围(半径)
    5. .point(18.231472,109.502083)); //中心点
    6. request.source().query(boolQuery).size(10000).trackTotalHits(true);
    7. SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

    2.geo_bounding_box矩形区域查询

    geo_bounding_box查询提供的是矩形内的搜索,需要提供左上角和右下角的顶点坐标。

    2.1 查询的DSL

    1. GET index_school/_search
    2. {
    3. "_source": [
    4. "name",
    5. "latitude",
    6. "longitude",
    7. "devideNo",
    8. "time"
    9. ],
    10. "query": {
    11. "geo_bounding_box":{
    12. "location":{
    13. "top_left":{ //设置左上角顶点坐标
    14. "lat": "18.431472",
    15. "lon": "109.502083"
    16. },
    17. "bottom_right":{ //设置右下角顶点坐标
    18. "lat": "18.231472",
    19. "lon": "109.202083"
    20. }
    21. }
    22. }
    23. }
    24. }

    2.2 java实现

    1. SearchRequest request = new SearchRequest(tableName);
    2. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    3. boolQuery.filter(QueryBuilders.geoBoundingBoxQuery("location") //指定索引字段
    4. .setCorners(inputDTO.getYMax(), inputDTO.getXMin(), //构造矩形
    5. inputDTO.getYMin(), inputDTO.getXMax()));
    6. request.source().query(boolQuery).size(10000).trackTotalHits(true);
    7. SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

    3.geo_polygon多边形区域查询

    geo_polygon比geo_bounding_box提供的地理范围功能更加灵活,它支持灵活多变的多边形内数据查询,使用该查询需要提供多边形所有顶点的坐标。

    3.1 查询的DSL

    1. GET index_school/_search
    2. {
    3. "query": {
    4. "geo_polygon":{
    5. "location":{
    6. "points":[
    7. {
    8. "lat": "20.219935",
    9. "lon": "109.700590"
    10. },
    11. {
    12. "lat": "20.118963",
    13. "lon": "109.865898"
    14. },
    15. {
    16. "lat": "20.148887",
    17. "lon": "110.1842848"
    18. },
    19. {
    20. "lat": "20.355594",
    21. "lon": "111.097193"
    22. },
    23. {
    24. "lat": "20.295775",
    25. "lon": "111.791273"
    26. }
    27. ]
    28. }
    29. }
    30. }
    31. }

    3.2 java实现

    1. String AREA_POINTS =
    2. "109.70059057645672,20.219935185668575," +
    3. "109.86589885747735,20.11896383759739," +
    4. "110.18428481460053,20.148887724639927," +
    5. "111.09719394252089,20.355594505110506," +
    6. "111.79127352756524,20.295775199436054," +
    7. "111.44955008175484,19.864326194135216," +
    8. "110.65937420024187,18.52295323361459," +
    9. "109.76478316052932,17.989118493905913," +
    10. "109.57997296428381,17.95228226006386";
    11. SearchRequest request = new SearchRequest(tableName);
    12. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    13. List points = new ArrayList<>();
    14. String[] strings = AREA_POINTS.split(",");
    15. for (int i = 0; i < strings.length; i = i + 2) {
    16. points.add(new GeoPoint(Double.valueOf(strings[i + 1]), Double.valueOf(strings[i])));
    17. }
    18. boolQuery.filter(QueryBuilders.geoPolygonQuery("location",points));
    19. request.source().query(boolQuery).size(10000).trackTotalHits(true);
    20. SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

  • 相关阅读:
    【离散数学】——刷题题库(范式)
    服务器正文22:linux内核网络模块笔记:收包、发包、各种内核参数上限、网络内核优化和容器网络虚拟化(8/2)
    字节面试问题
    Centos7.9 一键脚本部署 LibreNMS 网络监控系统
    Java项目:送水公司管理系统(java+SpringBoot+html+Mybatis+Mysql)
    Python学习笔记
    计算机毕设(附源码)JAVA-SSM基于的楼盘销售系统的设计与实现
    CSS经典布局--圣杯布局和双飞翼布局
    windows10系统安装nvm切换电脑node版本
    DigiCert代码签名证书
  • 原文地址:https://blog.csdn.net/linhaiyun_ytdx/article/details/126963460