美文网首页Elasticsearch程序员elasticsearch
Elasticsearch地理位置查询-Geo Distance

Elasticsearch地理位置查询-Geo Distance

作者: GhostStories | 来源:发表于2017-03-22 10:58 被阅读1225次

    官方文档:

    https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-geo-distance-query.html#_geohash_3

    欢迎访问本人博客:http://wangnan.tech

    索引mapping定义:

    索引中定义一个字段pin,添加一个属性location,type为geo_point

    "pin" : {
      "properties" : {
        "location" : {
          "type" : "geo_point"
            }
          }
        }
    

    DSL:

    报文中的包含一个match all的query , filter中的distance指定了距离范围,pin.location是经纬度

    {
    "bool" : {
        "must" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_distance" : {
                "distance" : "200km",
                "pin.location" : {
                    "lat" : 40,
                    "lon" : -70
                }
            }
        }
    }
    }
    

    代码:

    拼装 query 和 sort

               QueryBuilder builder = new GeoDistanceRangeQueryBuilder ("pin.location") 
                        .point(lat,lon)
                        .from("0km")  
                        .to("10000km")  
                        .includeLower(true)  
                        .includeUpper(false)  
                        .optimizeBbox("memory")  
                        .geoDistance(GeoDistance.ARC);  
         
                  GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location");  
                  GeoDistanceSortBuilder sort = new GeoDistanceSortBuilder("location");  
                  sort.unit(DistanceUnit.KILOMETERS); 
                  sort.order(SortOrder.ASC);  
                  sort.point(lat,lon); 
    

    构造dsl生产器

        
                SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource(); 
                sourceBuilder.query(QueryBuilders.boolQuery())                
                .must(builder)
                sourceBuilder.sort(sort);
    

    调用elasticsearch

        final SearchResponse response = executeGet(new ClientCallback<SearchResponse>() {
                @Override
                public ActionFuture<SearchResponse> execute(final Client client) {
                final SearchSourceBuilder sourceBuilder =    SearchParamUtils
                .genSearchSourceBuilderFromSearchParam(searchParam);  
                String[] indexNames = new String[aliasIndexNameList.size()];
                SearchRequest request = Requests.searchRequest(aliasIndexNameList.toArray(indexNames))
                .types(type);
                request.source(sourceBuilder.toString());
                if (searchParam.getSearchType() != null) {
                        request.searchType(searchParam.getSearchType());
                }
                    return client.search(request);
                }
            });
    

    获取每条记录的距离

                SearchResult searchResult = new SearchResult();
                SearchHits hits = response.getHits();
                for (SearchHit hit : hits.getHits()) {
                Object[] sortArray = hit.getSortValues();
                    if(sortArray!=null&&sortArray.length>0){
                        BigDecimal geoDis = new BigDecimal((Double) sortArray[sortArray.length-1]);
                        map.put("geoDistance", geoDis.setScale(0, BigDecimal.ROUND_HALF_DOWN));
                                System.out.println("距离" + hit.getSource().get("geoDistance"));
                    }
                }
                
    

    相关文章

      网友评论

      • 暖男大海哥:你好,请问你是用的版本是es5吗,因为我发现es5在环形查询是经常报错,org.elasticsearch.index.query.QueryShardException: [geo_distance_range] queries are no longer supported for geo_point field types. Use geo_distance sort or aggregations
      • 二更阅:你好,请问如果是通过注解的话,是使用哪个来呢?不使用mapping的方式创建、

      本文标题:Elasticsearch地理位置查询-Geo Distance

      本文链接:https://www.haomeiwen.com/subject/fxfonttx.html