ES简单快速使用实例

240 阅读1分钟

前提:1.导入RestHighLevelClient依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

2.将RestHighLevelClient Bean对象装配进spring容器

@Configuration
public class RestHighLevelClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
//192.168.115.131:9200是es的ip和端口
        return new RestHighLevelClient(RestClient.builder(HttpHost.create(192.168.115.131:9200)));
    }
}

一个基于es分布式搜索引擎的酒店搜索功能(包含复合查询,搜索字段高亮显示,指定排序,相关性算分查询[广告效果])

@Autowired
private RestHighLevelClient client;



//利用es搜索酒店信息功能
public PageResult<HotelDoc> queryList(RequestParams params) {
    SearchRequest request = new SearchRequest(ESconstant.HOTEL_INDEX);
    //封装查询条件
    getBoolQueryBuilder(params, request);
    //分页
    Integer size = params.getSize();
    Integer page = params.getPage();
    request.source().from((page - 1) * size).size(size);
    //指定排序(按照价格或者评论)
    String sortBy = params.getSortBy();
    if (!sortBy.equals("default")) {
        request.source().sort(sortBy, SortOrder.DESC);
    }
    String location = params.getLocation();
    //按照距离排序
    if (location != null) {

        request.source().sort(SortBuilders.geoDistanceSort("location", new GeoPoint(location)).order(SortOrder.ASC).unit(DistanceUnit.KILOMETERS));
    }
    SearchResponse response = null;
    try {
        //发出查询请求
        response = client.search(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //解析响应结果
    return getHotelDocPageResult(response);
}


//解析响应结果封装方法
    
private PageResult<HotelDoc> getHotelDocPageResult(SearchResponse response) {
    ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
    SearchHits responseHits = response.getHits();
    long value = responseHits.getTotalHits().value;
    for (SearchHit hit : responseHits.getHits()) {
        HotelDoc hotelDoc = JSON.parseObject(hit.getSourceAsString(), HotelDoc.class);

        Object[] sortValues = hit.getSortValues();
        if (sortValues.length > 0) {
            Object sortValue = sortValues[sortValues.length - 1];
            hotelDoc.setDistance(sortValue);
        }
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if (!CollectionUtils.isEmpty(highlightFields)) {
            // 根据字段名获取高亮结果
            HighlightField highlightField = highlightFields.get("name");
            if (highlightField != null) {
                // 获取高亮值
                String name = highlightField.getFragments()[0].string();
                // 覆盖非高亮结果
                hotelDoc.setName(name);
            }
        }
        hotelDocs.add(hotelDoc);
    }
    PageResult<HotelDoc> result = new PageResult<>();
    result.setHotels(hotelDocs);
    result.setTotal(value);
    return result;
}

//复合查询,编写查询条件
private void getBoolQueryBuilder(RequestParams params, SearchRequest request) {
    String key = params.getKey();
    String brand = params.getBrand();
    String city = params.getCity();
    String starName = params.getStarName();
    Integer minPrice = params.getMinPrice();
    Integer maxPrice = params.getMaxPrice();

    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    if (key == null || "".equals(key)) {
        boolQuery.must(QueryBuilders.matchAllQuery());
    } else {
        boolQuery.must(QueryBuilders.matchQuery("all", key));

    }
     // 高亮搜索字段
    request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
    if (brand != null && !"".equals(brand)) {
        boolQuery.filter(QueryBuilders.termQuery("brand", brand));
    }
    if (city != null && !"".equals(city)) {
        boolQuery.filter(QueryBuilders.termQuery("city", city));
    }
    if (starName != null && !"".equals(starName)) {
        boolQuery.filter(QueryBuilders.termQuery("starName", starName));
    }
    if (maxPrice != null && !"".equals(maxPrice)) {
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(maxPrice).gte(minPrice));
    }
    //当指定排序时,_score为null,不能为_score加分,相关性算分无作用
    FunctionScoreQueryBuilder functionScoreQuery =
            QueryBuilders.functionScoreQuery(
                    // 原始查询,相关性算分的查询
                    boolQuery,
                    // function score的数组
                    new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                            // 其中的一个function score 元素
                            new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                    // 过滤条件
                                    QueryBuilders.termQuery("isAD", true),
                                    // 算分函数
                                    ScoreFunctionBuilders.weightFactorFunction(10)
                            )
                    });
    //设置查询条件DSL
    request.source().query(functionScoreQuery);
}

根据品牌,星级,城市进行聚合查询功能

@Override
public Map<String, List<String>> getFilters(RequestParams params) {
    Map<String, List<String>> map = new HashMap<>();
    SearchRequest request = new SearchRequest(ESconstant.HOTEL_INDEX);
    getBoolQueryBuilder(params, request);
    request.source().size(0);
    request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(100));
    request.source().aggregation(AggregationBuilders.terms("starAgg").field("starName").size(100));
    request.source().aggregation(AggregationBuilders.terms("cityAgg").field("city").size(100));
    SearchResponse response = null;
    try {
        response = client.search(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
        e.printStackTrace();
    }
    Aggregations aggregations = response.getAggregations();
    List<String> brandAgg = getAggByName(aggregations, "brandAgg");
    map.put("brand", brandAgg);
    List<String> starAgg = getAggByName(aggregations, "starAgg");
    map.put("starName", starAgg);
    List<String> cityAgg = getAggByName(aggregations, "cityAgg");
    map.put("city", cityAgg);

    return map;
}

//根据聚合名称获取聚合结果
private List<String> getAggByName(Aggregations aggregations, String aggName) {
    // 4.1.根据聚合名称获取聚合结果
    Terms brandTerms = aggregations.get(aggName);
    // 4.2.获取buckets
    List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
    // 4.3.遍历
    List<String> brandList = new ArrayList<>();
    for (Terms.Bucket bucket : buckets) {
        // 4.4.获取key
        String key = bucket.getKeyAsString();
        brandList.add(key);
    }
    return brandList;
}

//根据自定义分词自动补全搜索条件
@Override
public List<String> getSuggestions(String prefix) {
    try {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.准备DSL
        request.source().suggest(new SuggestBuilder().addSuggestion(
                "suggestions",
                SuggestBuilders.completionSuggestion("suggestion")
                        .prefix(prefix)
                        .skipDuplicates(true)
                        .size(10)
        ));
        // 3.发起请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析结果
        Suggest suggest = response.getSuggest();
        // 4.1.根据补全查询名称,获取补全结果
        CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
        // 4.2.获取options
        List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
        // 4.3.遍历
        List<String> list = new ArrayList<>(options.size());
        for (CompletionSuggestion.Entry.Option option : options) {
            String text = option.getText().toString();
            list.add(text);
        }
        return list;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}