1. 程式人生 > >elasticsearch時間柱狀圖聚合java實現

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()));