ElasticSearch 实现分词全文检索 - 经纬度定位商家距离查询

目录

ElasticSearch 实现分词全文检索 - 概述
ElasticSearch 实现分词全文检索 - ES、Kibana、IK安装
ElasticSearch 实现分词全文检索 - Restful基本操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 索引操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作
ElasticSearch 实现分词全文检索 - 测试数据准备
ElasticSearch 实现分词全文检索 - term、terms查询
ElasticSearch 实现分词全文检索 - match、match_all、multimatch查询
ElasticSearch 实现分词全文检索 - id、ids、prefix、fuzzy、wildcard、range、regexp 查询
ElasticSearch 实现分词全文检索 - Scroll 深分页
ElasticSearch 实现分词全文检索 - delete-by-query
ElasticSearch 实现分词全文检索 - 复合查询
ElasticSearch 实现分词全文检索 - filter查询
ElasticSearch 实现分词全文检索 - 高亮查询
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 经纬度查询
ElasticSearch 实现分词全文检索 - 搜素关键字自动补全(suggest)
ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码

地图经纬度搜索

ES 中提供了一个数据类型 geo_point, 用来存储经纬度

创建ES索引

# 创建一个索引,指定 name,location
PUT /map
{
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 1
  },
  "mappings": { 
    "properties":{
      "name":{
        "type":"text"
      },
      "location":{
        "type":"geo_point"
      }
    } 
  }
}

百度地图经纬度:http://api.map.baidu.com/lbsapi/getpoint/index.html

添加数据

# 添加数据
PUT /map/_doc/1
{
  "name":"天安门",
  "location":{
    "lon":116.403119,
    "lat":39.915599
  }
}

PUT /map/_doc/2
{
  "name":"北京大学",
  "location":{
    "lon":116.316486,
    "lat":39.999416
  }
}

PUT /map/_doc/3
{
  "name":"清华大学",
  "location":{
    "lon":116.333267,
    "lat":40.010276
  }
}

ES地图搜索方式

  • geo_distance: 直线距离检索方式
    image
  • geo_bound_box:以两个点确定一个巨型,获取在矩形内的全部数据
    image
  • geo_polygon:以多个点,确定一个多边形,获取多边形内的全部数据
    image

实现地图检索

# 直接距离
POST /map/_search
{ 
  "query":{
    "geo_distance":{
      "location":{     #确定一个点
        "lon":116.433589,
        "lat":39.909235
      },
      "distance":3000,  # 2000 查不到,当前定位中,3公里内维护的数据(类似外卖)
      "distance_type":"arc"   # 指定形状为圆形,直接距离
    }
  }
}

# 左上、右下,确定巨型范围
POST /map/_search
{ 
  "query":{
    "geo_bounding_box":{
      "location":{
        "top_left":{       # 圆明园
          "lon":116.309695,
          "lat":40.013094
        },
        "bottom_right":{    # 天安门
          "lon":116.403119,
          "lat":39.915599
        }
      }
    }
  }
}

# 多点确定范围
POST /map/_search
{
  "query":{
    "geo_polygon":{
      "location":{
        "points":[
          { 
            "lon":116.31027,
            "lat":40.013315
          },
          { 
            "lon":116.335854,
            "lat":39.998282
          },{ 
            "lon":116.301359,
            "lat":39.992534
          }
        ]
      }
    }
  }
}

Java

@Test
void geoPolygon() throws Exception {
    String indexName = "map";
    RestHighLevelClient client = ESClient.getClient();

    //1. 创建SearchRequest对象
    SearchRequest request = new SearchRequest(indexName);

    //2. 指定查询条件
    List<GeoPoint> points = new ArrayList<>();
    points.add(new GeoPoint(40.013315, 116.31027));
    points.add(new GeoPoint( 39.998282,116.335854));
    points.add(new GeoPoint( 39.992534,116.301359));

    SearchSourceBuilder builder = new SearchSourceBuilder();
    builder.query(QueryBuilders.geoPolygonQuery("location", points));
    request.source(builder);

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

    //4. 输出返回值
    for (SearchHit hit : resp.getHits().getHits()) {
        System.out.println(hit.getSourceAsMap());
    }
}
posted @ 2023-03-21 12:39  VipSoft  阅读(266)  评论(0编辑  收藏  举报