最近有个需求,前端传入时间间隔,去elasticsearch按照时间间隔统计每个时间间隔内数据量。
- public List
> getCount(@RequestParam Integer time, @RequestParam String selectedDatedTime) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
- format.setTimeZone(TimeZone.getTimeZone(ZoneId.of(DateUtil.TIMEZONE_ZONE_ID)));
- Date date = CommonUtil.getDateByString(selectedDatedTime);
-
- Calendar fromDate = Calendar.getInstance();
- fromDate.setTime(date);
- fromDate.add(Calendar.HOUR_OF_DAY, -time);
-
- Calendar toDate = Calendar.getInstance();
- toDate.setTime(date);
-
- RangeQueryBuilder timeRangeQuery = QueryBuilders.rangeQuery(ApplicationConstant.TIMESTAMP)
- // .timeZone("Asia/Singapore")
- .gte(fromDate.getTimeInMillis())
- .lt(toDate.getTimeInMillis());
-
- String application = "";
- if (applications != null && applications.size() > 0){
- application = applications.get(0);
- }
- IndexCoordinates index = IndexCoordinates.of("xxxxxxx");
- DateHistogramInterval timeInterval = null;
- if(time==1){
- timeInterval= DateHistogramInterval.minutes(5);
- }else if(time==24 || time==6 ||time==12){
- timeInterval = DateHistogramInterval.hours(1);
- }else{
- timeInterval= DateHistogramInterval.hours(12);
- }
- Query sq = new NativeSearchQueryBuilder()
- .withQuery(timeRangeQuery)
- .addAggregation(AggregationBuilders.dateHistogram("date_histogram")
- .field(TIMESTAMP_FIELD_NAME)
- .fixedInterval(timeInterval)
- .minDocCount(0)
- .timeZone(ZoneId.of(DateUtil.TIMEZONE_ZONE_ID))
- .extendedBounds(new ExtendedBounds(fromDate.getTimeInMillis(), toDate.getTimeInMillis()))
- )
- .withPageable(Pageable.unpaged())
- .build();
- return esservice.getCountApi(sq, index);
- }
这里面的 timeInterval 就是设定间隔时间。
加入 extendedBounds 目的就是防止出现0数据不会返回,例如我只有8am到12am内有数据,现在是12am,timeInterval是一小时,总共时间跨度是12小时。如果不设置extendedBounds的话,date_histogram查询出来的聚合只会有8am-9am,9am-10am,10am-11am,11am-12am这几个的聚合,不会有8am之前的聚合出现,照理来说,会出现12个聚合,不管有没有数据都有聚合返回,只不过某些聚合出来docCount是0而已。所以需要加上这个条件
因为前端ui需要进行展示,就算没有数据也需要展示。例如这个chart的前半段,虽然聚合出来没有数据,但是也需要展示0数据。

这边是处理数据的service
- public List
> getCountApi(Query sq, IndexCoordinates esindex) { - HashMap
data = new HashMap<>(); - List
> list = new ArrayList<>(); - SearchHits
result = template.search(sq, HashMap.class, esindex); - Aggregations agg = result.getAggregations();
- if (agg != null) {
- ParsedDateHistogram histogram = agg.get("date_histogram");
- List
> innerlist = new ArrayList<>(); - for (Histogram.Bucket timebucket : histogram.getBuckets()) {
- HashMap
tempMap = new HashMap<>(); - ZonedDateTime zdt = (ZonedDateTime) timebucket.getKey();
- DateTime dt = new DateTime(zdt.toEpochSecond() * 1000L, DateTimeZone.forID(DateUtil.TIMEZONE_ZONE_ID));
- // String dateStr = dt.toString("yyyy-MM-dd HH:mm:ss");
- tempMap.put("x", dt.getMillis());
- tempMap.put("y", timebucket.getDocCount());
- innerlist.add(tempMap);
- }
- data.put("data", innerlist);
- data.put("name", NAME_OF_TYPE);
- list.add(data);
- }
- return list;
- }