zoukankan      html  css  js  c++  java
  • 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数据的下载地址

     

     

  • 相关阅读:
    基于MFC的Media Player播放器的制作(1---播放器界面的布局)
    Codeforces 1182
    Codeforces 1169
    Codeforces 1167
    Codeforces 1166
    Codeforces 1148
    *Codeforces 1162
    Codeforces 1159
    点分治
    高斯消元*
  • 原文地址:https://www.cnblogs.com/gqymy/p/13301035.html
Copyright © 2011-2022 走看看