elasticsearch时间柱状图聚合java实现

需求:统计每天有多少条数据,以及某字段的平均值。

1. 使用DateHistogramAggregationBuilder按天统计,再嵌入aggs取平均值。

如果要对结果进行排序,在 AggregationBuilders 加上 .order(Histogram.Order.COUNT_DESC)

        AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders
                .avg("avg_aggsName")
                .field("fieldName");
                
        DateHistogramAggregationBuilder dateHistogramAggregationBuilder = AggregationBuilders
                .dateHistogram("aggsName")
                .field("fieldName") //可以是time
                .dateHistogramInterval(DateHistogramInterval.DAY)
                .format("yyyy-MM-dd")
                .minDocCount(0L)
                .subAggregation(avgAggregationBuilder);

2. 如果再新增一条需求:只统计近一个月的数据。

那么就加一条filter,过滤后再聚合。


//日期限制
		QueryBuilder rangeBuilder = QueryBuilders
            .rangeQuery(aggsName)
            .format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
            .gte(timeRange.get("startTime").toString())
            .lte(timeRange.get("endTime").toString());
            
//        过滤后聚合 .missing(0)
        QueryBuilder queryBuilder = QueryBuilders
                .boolQuery()
                .filter(rangeBuilder);
                
3. 获取当天/一周内/一个月内起始时间
	private static Map<String, String> getTime(String period) {

        Map<String, String> timeRange = new HashMap<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        Calendar calendar = Calendar.getInstance();
        timeRange.put("endTime", simpleDateFormat.format(calendar.getTime()));

        switch (period) {

            case "week": {
                calendar.add(Calendar.DATE, -7);
            }
            break;

            case "month": {
                calendar.add(Calendar.MONTH, -1);
            }
            break;

            default: break;

        }

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        timeRange.put("startTime", simpleDateFormat.format(calendar.getTime()));
        return timeRange;

    }

4. 整合查询语句
		searchSourceBuilder
                .query(queryBuilder)
                .aggregation(dateHistogramAggregationBuilder);

        String query = searchSourceBuilder.toString();
        

需求:获取type/index下最新一条记录

首先用 matchAll 匹配所有数据,再根据时间排序。最终获取 getFirstHit,得到最新记录。(字段中最好包含time字段)

		QueryBuilder queryBuilder = QueryBuilders
                .matchAllQuery();
        
        searchSourceBuilder
                .query(queryBuilder)
                .sort("time", SortOrder.DESC);

输出结果

1. 获取 hits 数据:
		List<SearchResult.Hit<TESTCLASS, Void>> hits = result.getHits(TESTCLASS.class);
        List<TESTCLASS> userList = new ArrayList<>();
        for (SearchResult.Hit<TESTCLASS, Void> hit : hits) {
            userList.add(hit.source);
        }

2. 获取 aggs 里的 buckets 数据:
		MetricAggregation jsonAggs = searchResult.getAggregations();
		

日期柱状图

		Map<String,Object> map = new HashMap<>();
        DateHistogramAggregation histogram = jsonAggs.getDateHistogramAggregation("aggsName");
        for (DateHistogramAggregation.DateHistogram entry : histogram.getBuckets()) {
            map.put(entry.getTimeAsString(), entry.getCount());
        } 
   

求平均值

        AvgAggregation avg = jsonAggs.getAvgAggregation("avg_aggsName");
        result.put("avg_aggsName", Math.ceil(avg.getAvg()));

猜你喜欢

转载自blog.csdn.net/max_hu_/article/details/83859239