elasticsearch 的查询,聚合,统计总结

标签:val   无法   转换   统计   聚合函数   timeout   bag   个人   imp   

  • 配置组装适合自己的查询语句 利用 BoolQueryBuilder (布尔查询组装):
  • public class ElasticSearchBuilderQuery {
    /**

    • 构建基本查询 - 搜索关键字 (数据分词。按逗号)
    • @param searchMap
    • @return
      */
      public static BoolQueryBuilder buildBasicQuery(PageData searchMap) {
      // 构建布尔查询
      BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
      // 时间区间查询
      if(searchMap.get("startTime")!= null && searchMap.get("endTime") !=null){
      boolQueryBuilder.filter(QueryBuilders.rangeQuery("date").gte(searchMap.get("startTime")).lte(searchMap.get("endTime")).timeZone("Asia/Shanghai")); //timeZone这个参数很有必要,由于ES不管设置什么,都会转换为UTC格式,很搞
      }

      // 项目过滤
      if (StringUtils.isNotBlank(searchMap.get("project")+"") && searchMap.containsKey("project")){
          BoolQueryBuilder boolQueryBuilderProject = QueryBuilders.boolQuery();
          String[] projects = (String[]) searchMap.get("project");
          for(String project : projects){
              QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("project_ids",project);
              boolQueryBuilderProject.should().add(queryBuilder);
          }
          boolQueryBuilder.filter(boolQueryBuilderProject);
      }
      // 供应商过滤
      if(StringUtils.isNotBlank(searchMap.get("company")+"") && searchMap.containsKey("company")){
          BoolQueryBuilder boolQueryBuilderCompany = QueryBuilders.boolQuery();
          String[] companys = (String[]) searchMap.get("company");
          for(String company : companys){
              QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("company_ids",company);
              boolQueryBuilderCompany.should().add(queryBuilder);
          }
          boolQueryBuilder.filter(boolQueryBuilderCompany);
      }
      // 部门过滤
      if(StringUtils.isNotBlank(searchMap.get("dept")+"") && searchMap.containsKey("dept")){
          BoolQueryBuilder boolQueryBuilderDept = QueryBuilders.boolQuery();
          String[] depts = (String[]) searchMap.get("dept");
          for(String dept : depts){
              QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("dept_ids",dept);
              boolQueryBuilderDept.should().add(queryBuilder);
          }
          boolQueryBuilder.filter(boolQueryBuilderDept);
      }
      // 角色过滤
      if(StringUtils.isNotBlank(searchMap.get("role")+"") && searchMap.containsKey("role")){
          BoolQueryBuilder boolQueryBuilderRole = QueryBuilders.boolQuery();
          String[] roles = (String[]) searchMap.get("role");
          for(String role : roles){
              QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("role_ids",role);
              boolQueryBuilderRole.should().add(queryBuilder);
          }
          boolQueryBuilder.filter(boolQueryBuilderRole);
      }
      
      // 用户名过滤
      if(StringUtils.isNotBlank(searchMap.get("user_name")+"") && searchMap.containsKey("user_name")){
          QueryBuilder queryBuilder = QueryBuilders.termQuery("user_name.keyword",searchMap.get("user_name"));
          boolQueryBuilder.filter(queryBuilder);
      }
      return boolQueryBuilder;

      }
      }

    1. 组装聚合查询的语句
      elasticsearch 的查询,聚合,统计总结

    // 连接的index
    SearchRequest searchRequest = new SearchRequest();
    searchRequest.indices(searchIndex);
    searchRequest.types("analysed");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    // 自己组装查询
    BoolQueryBuilder queryBuilder = ElasticSearchBuilderQuery.buildBasicQuery(pageData);

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//格式化为年月
        // 基础查询
        QueryBuilder query  = QueryBuilders.boolQuery().must(queryBuilder);
    
        //script = "doc[‘date‘] +‘####‘+doc[‘user_name.keyword‘]";
        // 根据日期分组
        TermsAggregationBuilder aggByDate = AggregationBuilders.terms("by_date")
                .field("date").size(365);
        // 根据用户名分组
        TermsAggregationBuilder  aggByUser = AggregationBuilders.terms("by_userName")
                .field("user_name.keyword").size(10000);
        // 根据有效时间统计
        SumAggregationBuilder sum = AggregationBuilders.sum("sum").field("valid_time");
        // 根据持续时间统计
        SumAggregationBuilder duringSum = AggregationBuilders.sum("during_sum").field("during_time_sec");
        // 定义需要的返回值字段
        String[] returnField = new String[]{"user_name","date","sum","nickname"};
    
        TopHitsAggregationBuilder source = AggregationBuilders.topHits("source").fetchSource(returnField, new String[]{}).size(1);
        aggByDate.subAggregation(aggByUser.subAggregation(sum).subAggregation(duringSum).subAggregation(source));
        sourceBuilder.query(query).size(0);
        sourceBuilder.aggregation(aggByDate);
    
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(sourceBuilder);
    
                try {
            SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                        // 
              ParsedLongTerms byDate =(ParsedLongTerms) searchResponse.getAggregations().get("by_date");
            // 获取桶
            List<ParsedLongTerms.ParsedBucket> buckets = (List<ParsedLongTerms.ParsedBucket>) byDate.getBuckets();
            buckets.forEach(bucket -> {
                // 桶中数据通过自己的业务进行获取 后组装返回
                                // 通过的数据可以通过调试,获取sourceBuilder的值,通过Kb去查询查看,更好理解
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    1. 总结
      在初次使用es时,有很多概念不懂,在查询时,将查询的数据全部返回了,然后自己通过代码给做统计,这样的查询出来的所花的时间很多。通过使用聚合函数,查询出自己想要的数据,速度很快。
      注意点: (1)如果某个字段要进行分组时,那需要在建立mapping时,设置type为keyword。在没有设置keyword时,类型默认text,分组这个字段将没有结果。
      (2)通过日期区间查询时,需要设置timezone这个参数,又可能是我的配置不对,这个看个人,如果是date的日期相差一天的话,建立设置时区。
      (3)使用SumAggregationBuilder聚合后,该参数不可设置sub
      (4) 聚合后的数据无法分页,但是有size参数,官网是说不可以。

    elasticsearch 的查询,聚合,统计总结

    标签:val   无法   转换   统计   聚合函数   timeout   bag   个人   imp   

    原文地址:https://blog.51cto.com/12947828/2563499

    版权声明:完美者 发表于 2020-12-18 13:05:03。
    转载请注明:elasticsearch 的查询,聚合,统计总结 | 完美导航

    暂无评论

    暂无评论...