Java Elasticsearch 按一定时间间隔(timeInterval)循环查询数据

最近有个需求,前端传入时间间隔,去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数据。

Java Elasticsearch 按一定时间间隔(timeInterval)循环查询数据_第1张图片

 

 

这边是处理数据的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;
    }

 

你可能感兴趣的:(elk,java,elasticsearch,开发语言)