地图经纬度搜索
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: 直线距离检索方式
- geo_bound_box:以两个点确定一个巨型,获取在矩形内的全部数据
- geo_polygon:以多个点,确定一个多边形,获取多边形内的全部数据
实现地图检索
# 直接距离 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()); } }