ElasticsearchRestTemplate 聚合查询

语法如下:

POST /company/_search
{
  "aggs": {
    "NAME": { //指定结果的名称
      "AGG_TYPE": { //指定具体的聚合方法,
        TODO:  //# 聚合体内制定具体的聚合字段
      }
    }
    TODO:  //该处可以嵌套聚合
  }
}

聚合分析功能主要有指标聚合、桶聚合、管道聚合和矩阵聚合,常用的有指标聚合和桶聚合,本文主要看一下指标聚合和桶聚合怎么使用。

指标聚合

对某个字段取最大值max

【sql】
  select max(age) from company 
【ES】
  POST /company/_search
  {
    "aggs":{
      "max_age":{
        "max":{"field":"age"}
      }
    },
    "size":0 //size=0是为了只看聚合结果
  }

 结果如下:

{
    "aggregations": {
        "max_age": {
            "value": 64
        }
    }
}

elasticSearchRestTemplate java实现max

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
MaxAggregationBuilder max =AggregationBuilders.max("maxAge").field("age");
queryBuilder.withAggregations(max);
SearchHits search = elasticSearchRestTemplate.search(queryBuilder.build(), DeviceInfo.class);

if (search.hasAggregations()) {
   AggregationsContainer container = search.getAggregations();
   Aggregations aggregations = (Aggregations) container.aggregations();
   if (Objects.nonNull(aggregations)) {
       Max maxAge= aggregations.get("maxAge");
       log.info("计算 maxAge最大值:{} ", maxAge.getValue());
   }
}

 对某个字段取最小值min

【sql】
  select min(age) from company 
【ES】
  POST /company/_search
  {
      "aggs":{
        "min_age":{
          "min":{"field":"age"}
        }
      },
      "size":0
    }

 结果如下:

{
    "aggregations": {
        "min_age": {
            "value": 1
        }
    }
}

 java实现

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
MinAggregationBuilder min =AggregationBuilders.min("minAge").field("age");
queryBuilder.withAggregations(min);
SearchHits search = elasticSearchRestTemplate.search(queryBuilder.build(), DeviceInfo.class);

if (search.hasAggregations()) {
    AggregationsContainer container = search.getAggregations();
    Aggregations aggregations = (Aggregations) container.aggregations();
    if (Objects.nonNull(aggregations)) {
        Min minAge= aggregations.get("minAge");
        log.info("计算 minAge最小值:{} ", minAge.getValue());
    }
}

分组查询统计并分页

【sql】
  select p_key, count(running_state), count(use_state) from device_info group by p_key
【ES】

POST /device_info/_search
{
  "aggs": {
    "pKey_groupby": {
      "terms": {"field": "pKey"},
      "aggs": {
        "runningState_groupby": {
          "terms": {"field": "runningState"}
        },
        "useState_groupby": {
          "terms": {"field": "useState"}
        },
        "page":{
          "bucket_sort": {
            "from": 1,
            "size": 3
          }
        }
      }
    }
  },"size": 0
}

 结果

 java实现

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
TermsAggregationBuilder pKeyAggregation = AggregationBuilders.terms("pKey").field("pKey");
TermsAggregationBuilder runningStateAggregation =AggregationBuilders.terms("runningState").field("runningState");
TermsAggregationBuilder useStateAggregation =AggregationBuilders.terms("useState").field("useState");
BucketSortPipelineAggregationBuilder bucket = new BucketSortPipelineAggregationBuilder("page",null).from(pageNum-1).size(pageSize);

pKeyAggregation.subAggregation(runningStateAggregation);
pKeyAggregation.subAggregation(useStateAggregation);
pKeyAggregation.subAggregation(bucket);
queryBuilder.withAggregations(pKeyAggregation);
NativeSearchQuery build = queryBuilder.build();
SearchHits search = elasticSearchRestTemplate.search(build, DeviceInfo.class);
Map<String,Integer> voMap = new HashMap<>();
if(search.hasAggregations()) {
    AggregationsContainer container = search.getAggregations();
    Aggregations aggregations = (Aggregations) container.aggregations();
    Terms pTerms = aggregations.get("pKey");
    int inx =0;
    for (Terms.Bucket bk : pTerms.getBuckets()) {
        DeviceBeanVo vo = new DeviceBeanVo();
        String key = bk.getKeyAsString();
        Integer cNum = Long.valueOf(bk.getDocCount()).intValue();
        vo.setProductName(key);
        vo.setAllNum(cNum);
        vo.setYjh(0);
        vo.setZx(0);
        vo.setLx(0);
        vo.setYqy(0);
        Aggregations aggs = bk.getAggregations();
        Terms rTerms = aggs.get("runningState");
        for (Terms.Bucket r : rTerms.getBuckets()) {
            String rKey = r.getKeyAsString();
            Integer rNum = Long.valueOf(r.getDocCount()).intValue();
            if(rKey.equals(RunStateEnum.YZX.getStatus().toString())){
                vo.setYjh(vo.getYjh()+rNum);
                vo.setZx(vo.getZx()+rNum);
            }else if(rKey.equals(RunStateEnum.YLX.getStatus().toString())){
                vo.setLx(vo.getLx()+rNum);
            }
        }
        Terms uTerms = aggs.get("useState");
        for (Terms.Bucket u : uTerms.getBuckets()) {
            String uKey = u.getKeyAsString();
            Integer uNum = Long.valueOf(u.getDocCount()).intValue();
            if(uKey.equals(StateEnum.YFB.getStatus().toString())){
                vo.setYqy(vo.getYqy()+uNum);
            }
        }
        list.add(vo);
        voMap.put(key,inx);
        inx++;
    }
}

复杂式查询

POST /device_info/_search
{
  "aggs": {
    "pKey_groupby": {
      "terms": {
        "field": "pKey"
      },
      "aggs": {
        "pKey_top":{
          "top_hits":{
            "size": 1
          }
        },
        "runningState_groupby": {
          "terms": {
            "field": "runningState"
          }
        },
        "useState_groupby": {
          "terms": {
            "field": "useState"
          }
        },
        "bucket_truncate": {
          "bucket_sort": {
            "from": 0,
            "size": 10,
            "sort": []
          }
        }
      }
    },
    "pKey_distinct": {
      "cardinality": {
        "field": "pKey"
      }
    }
  },"size": 0
}

 java 实现
Integer pageNum = null==req.getPageNum()?1:req.getPageNum();
Integer pageSize = null==req.getPageSize()?10:req.getPageSize();
List<DeviceBeanVo> list = new ArrayList<>();
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
ZngxUser user = SecurityUtils.getUser();
if(user.getFlag().equals("1")){
    BoolQueryBuilder builder = QueryBuilders.boolQuery();
    builder.must(QueryBuilders.termQuery("tenantId",user.getTenantId()));
    queryBuilder.withQuery(builder);
}
Integer allNum = 0;
int start = (pageNum-1)*pageSize;
TermsAggregationBuilder pKeyAggregation = AggregationBuilders.terms("pKey").field("pKey");//要分组的字段
CardinalityAggregationBuilder pAllAggregation =AggregationBuilders.cardinality("pAll").field("pKey");//要distinct 统计的字段
TopHitsAggregationBuilder topAggregation=AggregationBuilders.topHits("device").size(1);//统计后匹配的一条数据
TermsAggregationBuilder runningStateAggregation =AggregationBuilders.terms("runningState").field("runningState");
TermsAggregationBuilder useStateAggregation =AggregationBuilders.terms("useState").field("useState");
BucketSortPipelineAggregationBuilder bucket = new BucketSortPipelineAggregationBuilder("page",null).from(start).size(pageSize);//桶分页
pKeyAggregation.subAggregation(topAggregation);
pKeyAggregation.subAggregation(runningStateAggregation);
pKeyAggregation.subAggregation(useStateAggregation);
pKeyAggregation.subAggregation(bucket);
queryBuilder.withAggregations(pKeyAggregation);
queryBuilder.withAggregations(pAllAggregation);
NativeSearchQuery build = queryBuilder.build();

SearchHits search = elasticSearchRestTemplate.search(build, DeviceInfo.class);
Set<String> kSet = new HashSet<>();
if(search.hasAggregations()) {
    AggregationsContainer container = search.getAggregations();
    Aggregations aggregations = (Aggregations) container.aggregations();
    Terms pTerms = aggregations.get("pKey");
    Cardinality cardinality = aggregations.get("pAll");
    allNum=Long.valueOf(cardinality.getValue()).intValue();
    for (Terms.Bucket bk : pTerms.getBuckets()) {
        DeviceBeanVo vo = new DeviceBeanVo();
        String key = bk.getKeyAsString();
        kSet.add(key);
        Integer cNum = Long.valueOf(bk.getDocCount()).intValue();
        vo.setAllNum(cNum);
        vo.setPKey(key);
        vo.setYjh(0);
        vo.setZx(0);
        vo.setLx(0);
        vo.setYqy(0);
        Aggregations aggs = bk.getAggregations();
        TopHits topHits = aggs.get("device");
        org.elasticsearch.search.SearchHits hits =topHits.getHits();
        org.elasticsearch.search.SearchHit  hit =hits.getHits()[0];
        DeviceInfo hitDev = BeanUtil.copyProperties(hit.getSourceAsMap(),DeviceInfo.class);
        vo.setProductName(hitDev.getProductName());
        Terms rTerms = aggs.get("runningState");
        for (Terms.Bucket r : rTerms.getBuckets()) {
            String rKey = r.getKeyAsString();
            Integer rNum = Long.valueOf(r.getDocCount()).intValue();
            if(rKey.equals(RunStateEnum.YZX.getStatus().toString())){
                vo.setYjh(vo.getYjh()+rNum);
                vo.setZx(vo.getZx()+rNum);
            }else if(rKey.equals(RunStateEnum.YLX.getStatus().toString())){
                vo.setLx(vo.getLx()+rNum);
            }
        }
        Terms uTerms = aggs.get("useState");
        for (Terms.Bucket u : uTerms.getBuckets()) {
            String uKey = u.getKeyAsString();
            Integer uNum = Long.valueOf(u.getDocCount()).intValue();
            if(uKey.equals(StateEnum.YFB.getStatus().toString())){
                vo.setYqy(vo.getYqy()+uNum);
            }
        }
        list.add(vo);
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值