elasticsearch時間柱狀圖聚合java實現
阿新 • • 發佈:2018-11-08
需求:統計每天有多少條資料,以及某欄位的平均值。
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()));