ElasticSearch聚合实例

public List<AlarmTop5Vo> getAlarmTimesTop5(Integer beforeDays, String regionId) {

        List<AlarmTop5Vo> result = new ArrayList<>();

        RestHighLevelClient client = null;
        try {
            client = EsPoolUtil.getClient();
			//创建搜索请求对象
            SearchRequest searchRequest = new SearchRequest("index_name").types("type_name");
			//ES脚本,提供+、-、*、/等运算
            Script script = new Script("doc['taskId'].value +'####'+doc['roadId'].value");

            LocalDateTime zeroTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
            long endTimeStamp = zeroTime.plusDays(1L).toInstant(ZoneOffset.of("+8")).toEpochMilli();
            long startTimeStamp = zeroTime.minusDays(beforeDays).toInstant(ZoneOffset.of("+8")).toEpochMilli();
            //自定义聚合名字
            String tag5AggName = "top5Agg";
            String latestRoadNameAggName = "latestRoadNameAgg";
            //构建请求条件,先布尔查询再进行聚合
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                    .query(QueryBuilders.boolQuery()
                    //布尔查询的3个条件,size=0是因为不在意查询结果是什么,而在意aggs的结果,加快返回速度
                            .must(QueryBuilders.rangeQuery("timestamp").gte(startTimeStamp).lt(endTimeStamp))
                            .must(QueryBuilders.termQuery("isWarn", "1"))
                            .must(QueryBuilders.termQuery("groupId", regionId)))
                    .size(0)
                    //脚本运算完进行倒叙排序,输出前五个值
                    .aggregation(AggregationBuilders.terms(tag5AggName)
                            .script(script).order(Terms.Order.count(false)).size(5)
                    //tag5AggName后再嵌套一个聚合latestRoadNameAggName,只返回一个字段roadName,且时间戳最大的
                            .subAggregation(AggregationBuilders.topHits(latestRoadNameAggName).sort("timestamp", SortOrder.DESC).fetchSource("roadName", null).size(1))
                    );
            //将搜索对象SearchSourceBuilder添加到搜索对象中
            searchRequest.source(searchSourceBuilder);
			//发送搜索请求并得到搜索响应对象SearchResponse 
            SearchResponse searchResponse = client.search(searchRequest);
			//满足聚合条件的文档会被放到桶里面,遍历桶
            MultiBucketsAggregation top5Agg = searchResponse.getAggregations().get(tag5AggName);
            List<? extends MultiBucketsAggregation.Bucket> buckets = top5Agg.getBuckets();
            buckets.forEach(bucket -> {
            	//获取嵌套聚合里的字段值
                ParsedTopHits latestRoadNameAgg = bucket.getAggregations().get(latestRoadNameAggName);
                SearchHit searchHit = latestRoadNameAgg.getHits().getAt(0);
                String roadName = searchHit.getSource().get("roadName").toString();
                long count = bucket.getDocCount();
                AlarmTop5Vo vo = new AlarmTop5Vo();
                vo.setMonitorSite(roadName);
                vo.setTimes(count);
                result.add(vo);
            });
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (client != null) {
                EsPoolUtil.returnClient(client);
            }
        }
        return new ArrayList<>();
    }

              GET /index_name/type_name
              {
                "size": 0,
                "query": {
                  "bool": {
                    "must": [
                      {
                        "range": {
                          "timestamp": {
                            "gte": 1589004201387,
                            "lte": 1589004201550
                          }
                        }
                      },
                      {
                        "term": {
                          "isWarn": {
                            "value": "1"
                          }
                        }
                      }
                    ]
                  }
                },
                "aggs": {
                  "top5Agg": {
                    "terms": {
                       "script": "doc['taskId'].value +'####'+doc['roadId'].value",
                       "order": {
                         "_count": "desc"
                       },
                       "size": 5
                    },
                    "aggs": {
                     "latestRoadNameAgg": {
                       "top_hits": {
                         "_source": {"includes": "roadName"},
                         "sort": [{
                           "timestamp": {
                             "order": "asc"
                           }
                         }],
                         "size": 1
                       }
                     }
                   }
                  }
                }
              }
             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值