Elasticsearch程序员elasticsearch

Elasticsearch地理位置查询-Geo Distance

2017-03-22  本文已影响1225人  GhostStories

官方文档:

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"));
                }
            }
            
上一篇下一篇

猜你喜欢

热点阅读