SpringBoot实现ES简单搜索和推荐

1 ES7.6的高级客户端

// ES高级客户端
public RestHighLevelClient restHighLevelClient(){
    RestClientBuilder restClientBuilder = RestClient.builder(
            new HttpHost("127.0.0.1", 9200, "http"),
            new HttpHost("192.168.128.11", 9200, "http"));
    return new RestHighLevelClient(restClientBuilder);
}

2 ES简单搜索数据

public List<Map<String, Object>> query() {
    String keyword = "中国";
    // 1 建立搜索规则

    // 建立多字段查询,字段名称是content和title
    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword);
    multiMatchQueryBuilder.field("content");
    multiMatchQueryBuilder.field("title");

    /*
    // 单字段查询
    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", keyword);
    sourceBuilder.query(matchQueryBuilder);
    */

    // Bool查询
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(multiMatchQueryBuilder);

    // 过滤器,过滤含有“绿色”的数据
    boolQueryBuilder.filter(QueryBuilders.matchQuery("content", "绿色"));

    // 过滤器,过滤日期在2016-01-01到2020-01-01之间的数据,注意日期格式必须是“yyyy-MM-dd HH:mm:ss”或“yyyy-MM-dd”,字段的type是date,format是yyyy-MM-dd,如果格式错误搜索出的数据有问题
    boolQueryBuilder.filter(QueryBuilders.rangeQuery("date").gte("2016-01-01").lte("2020-01-01"));

    // 2 建立查询
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(boolQueryBuilder);

    // 设置起始页
    sourceBuilder.from(0);
    // 设置一页的数据量,默认是10条数据
    sourceBuilder.size(100);
    // 设置超时
    sourceBuilder.timeout(new TimeValue(6, TimeUnit.SECONDS));

    // 设置高亮
    HighlightBuilder highlightBuilder = new HighlightBuilder();
    highlightBuilder.requireFieldMatch(false);
    highlightBuilder.field("content");
    highlightBuilder.field("title");
    highlightBuilder.preTags("<em>");
    highlightBuilder.postTags("</em>");
    sourceBuilder.highlighter(highlightBuilder);

    // 设置SearchRequest,可以指定多个索引,默认是所有索引
    SearchRequest request = new SearchRequest("website", "article");
    request.source(sourceBuilder);

    // 获取返回值
    List<Map<String, Object>> data = new ArrayList<>();
    try {
        SearchResponse response = this.restHighLevelClient.search(request, RequestOptions.DEFAULT);
        for (SearchHit hit: response.getHits().getHits()) {
            // 获取得SourceMap
            Map<String, Object> sourceMap = hit.getSourceAsMap();

            // 获取高亮
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField title = highlightFields.get("title");

            StringBuilder highlightTitle = new StringBuilder();
            if (title != null) {
                Text[] fragment = title.fragments();
                for (Text text : fragment) {
                    highlightTitle.append(text);
                }
            }
            // Replace the title
            if (highlightTitle.length() > 0) {
                sourceMap.put("title", highlightTitle.toString());
            }

            HighlightField content = highlightFields.get("content");
            StringBuilder highlightSummary = new StringBuilder();
            if (content != null) {
                Text[] fragment = content.fragments();
                for (Text text : fragment) {
                    highlightSummary.append(text);
                }
            }

            // 将highlightSummary替换sourceMap的content即可
            if (highlightSummary.length() > 0) {
                sourceMap.put("content", highlightSummary.toString());
            }

            // Add the list
            data.add(sourceMap);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
    return data;
}

3 CompletionSuggest推荐

// title的类型是"type": "completion",index不能是true(索引功能关闭)
// 完整推荐, 例如:keyword=中国,则会推荐“中国经济不断发展,中国进入世贸组织”(title的整个字段的内容)
public Set<String> completionSuggestData(String keyword){
    // 设置CompletionSuggestion
    CompletionSuggestionBuilder completionSuggestion = SuggestBuilders.completionSuggestion("title").prefix(keyword).size(20);
    SuggestBuilder suggestBuilder = new SuggestBuilder();
    suggestBuilder.addSuggestion("suggest_user", completionSuggestion);

    // 将completionSuggestion添加到searchSourceBuilder中
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // 设置超时时间
    searchSourceBuilder.timeout(new TimeValue(2, TimeUnit.SECONDS));
    searchSourceBuilder.suggest(suggestBuilder);

    // 将searchSourceBuilder添加到searchRequest中
    SearchRequest searchRequest = new SearchRequest("paper_db");
    searchRequest.source(searchSourceBuilder);    
    
    // 存储suggest
    HashSet<String> data = new HashSet<String>();
    try {
        // 读取suggest
        SearchResponse searchResponse = this.restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        Suggest suggest = searchResponse.getSuggest();

        if(suggest != null){
            CompletionSuggestion result = suggest.getSuggestion("suggest_user");
            for ( CompletionSuggestion.Entry entrys : result.getEntries()) {
                for(Suggest.Suggestion.Entry.Option option: entrys.getOptions()){
                    if(option != null){
                        // Remove special char and repeat data
                        data.add(option.getText().toString());
                    }
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return data;
}

4 TermSuggest推荐

// 推荐相似的词和短语
// 例如:keyword=中国人民,则会推荐“中国企业, 中国经济, 中国移动, 中国国际”(数据库里必须有相关的字段数据)
public Set<String> termSuggestData(String keyword){
    // 建立 TermSuggestionBuilder
    TermSuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion("title").text(keyword).size(100);
    SuggestBuilder suggestBuilder = new SuggestBuilder();
    suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder);

    // 建立SearchSourceBuilder,添加suggest
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.timeout(new TimeValue(2, TimeUnit.SECONDS));
    searchSourceBuilder.suggest(suggestBuilder);

    // 将searchSourceBuilder添加到searchRequest中
    SearchRequest searchRequest = new SearchRequest("paper_db");
    searchRequest.source(searchSourceBuilder);

    // 存储suggest
    HashSet<String> data = new HashSet<String>();
    try {
        // 读取suggest
        SearchResponse searchResponse = this.restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        Suggest suggest = searchResponse.getSuggest();

        if (suggest != null) {
            TermSuggestion result = suggest.getSuggestion("suggest_user");
            for (TermSuggestion.Entry entry : result.getEntries()) {
                for (Suggest.Suggestion.Entry.Option option : entry.getOptions()) {
                    if (option != null) {
                        // Remove special char and repeat data
                        data.add(option.getText().toString());
                    }
                }
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
    return data;
}


版权声明:本文为make_progress原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>