ElasticSearch SearchApi 高亮搜索


@Component
public class SearchApi {

    @Autowired
    private RestHighLevelClient client;
    @Autowired
    @Qualifier("searchListener")
    private ActionListener listener;

    public String termQuery(String indices, String name, String value){
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery(name, value));
        //分頁
        sourceBuilder.from(0);
        sourceBuilder.size(5);
        //超時時間設置
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(sourceBuilder);
        return getHits(searchRequest);
    }

    public String matchQuery(String indices, String fieldName, String value){
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //模糊搜索  設置前綴長度  設置最大擴展選項來控制查詢的模糊過程
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder(fieldName, value)
                .fuzziness(Fuzziness.AUTO)
                .prefixLength(0)
                .maxExpansions(10);

        sourceBuilder.query(matchQueryBuilder);
        searchRequest.source(sourceBuilder);
        return getHits(searchRequest);
    }

    public String highLightQuery(String indices, String name, String text, String... field){
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery(name, text).prefixLength(0));
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        for (String s : field) {
            highlightBuilder.field(s);
        }
        highlightBuilder.preTags("<span style=\"color:yellow\">");
        highlightBuilder.postTags("</span>");
        highlightBuilder.highlighterType("unified");
//        highlightBuilder.requireFieldMatch(true);
//        highlightBuilder.numOfFragments(0);
        searchSourceBuilder.highlighter(highlightBuilder);

        searchSourceBuilder.from(0);
        searchSourceBuilder.size(40);
        searchRequest.source(searchSourceBuilder);
        return getHits(searchRequest, field);
    }

    public String aggregationsQuery(String indices, String aggKey, String avgKey, String termField, String field){
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        /**
         * 匯總  通過首先創建適當的AggregationBuilder,然后在SearchSourceBuilder上設置它,可以將聚合添加到搜索中
         * Building Aggregations頁面提供了所有可用聚合的列表,以及它們對應的AggregationBuilder對象和AggregationBuilders helper方法
         * AggregationBuilders.terms 相當於sql中的group by;  terms值自定義 termField為需要分組的key
         * .subAggregation()相當於count
         * 獲取不同性別的總人數 select gender, count(*) as termField from bank group by gender   #(gender = field)
         */
        TermsAggregationBuilder aggregation = AggregationBuilders.terms(aggKey).field(termField);
//        aggregation.subAggregation(AggregationBuilders.avg(avgKey).field(field));
        sourceBuilder.aggregation(aggregation);
        searchRequest.source(sourceBuilder);
        return getAggregations(searchRequest, aggKey, avgKey);
    }

    public String suggestionQuery(String indices, String fieldname, String text, String name){
        SearchRequest searchRequest = new SearchRequest(indices);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        SuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion(fieldname).text(text);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion(name, termSuggestionBuilder);
        sourceBuilder.suggest(suggestBuilder);
        searchRequest.source(sourceBuilder);
        return suggestionSendSearch(searchRequest, name);
    }

    public String getHits(SearchRequest searchRequest, String... highLightField){
        SearchResponse searchResponse = syncSendSearch(searchRequest);
        StringBuilder result = new StringBuilder();
        SearchHits hits = searchResponse.getHits();
//        TotalHits totalHits = hits.getTotalHits();
        //命中的總次數,必須在totalHits.relation上下文中解釋
//        long numHits = totalHits.value;
        //命中的次數是准確的(EQUAL_TO)還是總數的下限(GREATER_THAN_OR_EQUAL_TO)
//        TotalHits.Relation relation = totalHits.relation;
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            //它允許您返回文檔源,可以是簡單的json字符串,也可以是鍵/值對的映射。
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//            List<Object> users = (List<Object>) sourceAsMap.get(field);
//            Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get(field);
//如果請求,可以從結果中的每個SearchHit中檢索突出顯示的文本片段。
            // hit對象提供了對字段名到HighlightField實例的映射的訪問,每個實例都包含一個或多個高亮顯示的文本片段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if(highlightFields.size() > 0 && highLightField != null){
                for (String s : highLightField) {
                    HighlightField highlight = highlightFields.get(s);
                    Text[] fragments = highlight.fragments();
                    String fragmentString = fragments[0].string();
                    //替換為高亮
                    sourceAsMap.put(s, fragmentString);
                }
            }
            // 在此映射中,常規字段按字段名進行鍵控,並包含字段值。多值字段作為對象列表返回,嵌套對象作為另一個鍵/值映射返回
            String sourceAsString = hit.getSourceAsString();
            Gson gson = new Gson();
            result.append(gson.toJson(sourceAsMap));
        }

        return result.toString();
    }

    //可以通過首先獲取聚合樹的根、聚合對象,然后通過名稱獲取聚合,從SearchResponse中檢索聚合
    public String getAggregations(SearchRequest searchRequest, String aggKey, String avgKey){
        SearchResponse searchResponse = syncSendSearch(searchRequest);
        Aggregations aggregations = searchResponse.getAggregations();
        Map map = aggregations.getAsMap();
        Terms byCompanyAggregation = aggregations.get(aggKey);
        List list = byCompanyAggregation.getBuckets();
        MultiBucketsAggregation.Bucket elasticBucket = byCompanyAggregation.getBucketByKey(aggKey);
        Avg averageAge = elasticBucket.getAggregations().get(avgKey);
        double avg = averageAge.getValue();
        //注意,如果按名稱訪問聚合,則需要根據請求的聚合類型指定聚合接口,否則將拋出ClassCastException
        //這將拋出一個異常,因為“by_company”是一個術語聚合,但我們試圖以范圍聚合的形式檢索它
//        Range range = aggregations.get(aggKey);

        //還可以將所有聚合作為映射訪問,映射是由聚合名稱鍵入的。在這種情況下,需要顯式地轉換到適當的聚合接口
//        Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
//        Terms companyAggregation = (Terms) aggregationMap.get(aggKey);

        //還有一些getter方法以列表的形式返回所有頂級聚合
//        List<Aggregation> aggregationList = aggregations.asList();
//        for (Aggregation agg : aggregations) {
//            String type = agg.getType();
//            if (type.equals(TermsAggregationBuilder.NAME)) {
//                Terms.Bucket elasticBucket2 = ((Terms) agg).getBucketByKey("Elastic");
//                long numberOfDocs = elasticBucket2.getDocCount();
//            }
//        }
        return avg + "";
    }

    public String suggestionSendSearch(SearchRequest searchRequest, String name){
        SearchResponse searchResponse = syncSendSearch(searchRequest);
        StringBuilder result = new StringBuilder();
        Suggest suggest = searchResponse.getSuggest();
        TermSuggestion termSuggestion = suggest.getSuggestion(name);
        for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {
            for (TermSuggestion.Entry.Option option : entry) {
                String suggestText = option.getText().string();
                result.append(suggestText);
            }
        }

        return result.toString();
    }

    public SearchResponse syncSendSearch(SearchRequest searchRequest){
        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            RestStatus status = searchResponse.status();
            TimeValue took = searchResponse.getTook();
            Boolean terminatedEarly = searchResponse.isTerminatedEarly();
            boolean timedOut = searchResponse.isTimedOut();

        }catch (Exception e){
            e.printStackTrace();
        }

        return searchResponse;
    }

}

這是數據

 

 es官方rest官方文檔 index中有bank數據的下載地址

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM