Es 查询(按年月日分组统计)

参考博客:https://www.tizi365.com/archives/949.html

1、Es 时间聚合单位

public class DateHistogramInterval implements Writeable, ToXContentFragment {
    public static final DateHistogramInterval SECOND = new DateHistogramInterval("1s");
    public static final DateHistogramInterval MINUTE = new DateHistogramInterval("1m");
    public static final DateHistogramInterval HOUR = new DateHistogramInterval("1h");
    public static final DateHistogramInterval DAY = new DateHistogramInterval("1d");
    public static final DateHistogramInterval WEEK = new DateHistogramInterval("1w");
    public static final DateHistogramInterval MONTH = new DateHistogramInterval("1M");
    public static final DateHistogramInterval QUARTER = new DateHistogramInterval("1q");
    public static final DateHistogramInterval YEAR = new DateHistogramInterval("1y");
}

2、分组统计字段

        DateHistogramAggregationBuilder histogramAggregationBuilder = null;
         //eg:day
            histogramAggregationBuilder = AggregationBuilders.dateHistogram((String) dimensionMap.get(ringAnalysisDto.getTimeDimension()))
                    .dateHistogramInterval(interval).field("create_time")
                    .subAggregation(AggregationBuilders.sum("totalId").field("orginal_id"))
                    .subAggregation(AggregationBuilders.sum("totalAge").field("age"));

3、统计结果获取

 Aggregations aggregations = searchResponse.getAggregations();
        Histogram aggregation = aggregations.get(dimensionMap.get(index).toString());
        for (Histogram.Bucket bucket:aggregation.getBuckets()) {

            String timeKey = bucket.getKeyAsString();
            JSONObject jsonObject = new JSONObject();
            NumericMetricsAggregation.SingleValue totalId = (NumericMetricsAggregation.SingleValue) bucket.getAggregations().getAsMap().get("totalId");
            NumericMetricsAggregation.SingleValue totalAge = (NumericMetricsAggregation.SingleValue)bucket.getAggregations().getAsMap().get("totalAge");
            jsonObject.putIfAbsent("timeKey",timeKey);
            jsonObject.putIfAbsent("idSum",totalId.value());
            jsonObject.putIfAbsent("ageSum",totalAge.value());

            jsonList.add(jsonObject);
        }
    List<JSONObject> rateList = calculateValueList(jsonList);

4、计算百分比

    private List<JSONObject> calculateValueList(List<JSONObject> list) {
        List<JSONObject> rateList = new ArrayList<>();
        for(int i =0;i< list.size();i++){
            JSONObject jsonObject = new JSONObject();
            Double idSum = (Double)list.get(i).get("idSum");
            Double ageSum = (Double)list.get(i).get("ageSum");
//            Double idSum1 = (Double)list.get(i+1).get("idSum");
//            Double ageSum1 = (Double)list.get(i+1).get("ageSum");
            String idRate = getRate(idSum, ageSum);
            //String ageRate = getRate(ageSum, ageSum1);
            jsonObject.putIfAbsent("time",list.get(i).get("timeKey"));
            jsonObject.putIfAbsent("idRate",idRate);
            //jsonObject.putIfAbsent("ageRate",ageRate);
            rateList.add(jsonObject);
        }
        return rateList;
    }

    public static String getRate(Double value,Double totalSum){
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        String result = numberFormat.format((Double)value/(Double)totalSum*100);
        return result;
    }

##############全部代码逻辑如下#############

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.NumericMetricsAggregation;
import org.springframework.stereotype.Service;

import java.text.NumberFormat;
import java.util.*;

/**
 * @program: datacenter
 * @description: 按年月日周统计分析
 * @author: yang
 * @create: 2021-02-01 10:20
 */
@Service
public class AnalysisServiceImpl implements AnalysisService {
    
    private  final String RING_ANALYSIS_INDEX = "goods";

    public final static Map dimensionMap = new HashMap();
    static {
        dimensionMap.put("day", "by_day");
        dimensionMap.put("week", "by_week");
        dimensionMap.put("month", "by_month");
        dimensionMap.put("channel", "by_channel");
        dimensionMap.put("project", "by_project");
        dimensionMap.put("province", "by_province");
    }
    private  TransportClient esTransportClient;

    public RingAnalysisServiceImpl(TransportClient esTransportClient) {
        this.esTransportClient = esTransportClient;
    }

    @Override
    public List getGraphData(RingAnalysisDto ringAnalysisDto) {

        List<JSONObject>  jsonList = new ArrayList<>();
        //参数校验
        String dimension = ringAnalysisDto.getProjectDimension() != null ? ringAnalysisDto.getProjectDimension() :
                ringAnalysisDto.getPopularizeDimension()!= null ?ringAnalysisDto.getPopularizeDimension():
                        ringAnalysisDto.getProvinceDimension() != null ?ringAnalysisDto.getProvinceDimension() : null;

        String timeDimension = ringAnalysisDto.getTimeDimension();

        DateHistogramInterval dateHistogramInterval =   "day".equals(timeDimension) ? DateHistogramInterval.DAY :
                  "week".equals(timeDimension) ? DateHistogramInterval.WEEK :
                        "month".equals(timeDimension) ? DateHistogramInterval.MONTH:DateHistogramInterval.DAY;

        String index = dimension !=null ? dimension : timeDimension;
        if(Objects.isNull(dimension) && Objects.isNull(timeDimension)) {return  null;}
        
        //组件条件
        SearchResponse searchResponse = esTransportClient.prepareSearch(RING_ANALYSIS_INDEX)
                .setTypes("_doc")
               // .setQuery(this.filterBaseConditions(ringAnalysisDto))
                .addAggregation(this.filterAggConditions(ringAnalysisDto,dateHistogramInterval,dimension)).get();

        //获取数据
        Aggregations aggregations = searchResponse.getAggregations();
        Histogram aggregation = aggregations.get(dimensionMap.get(index).toString());
        for (Histogram.Bucket bucket:aggregation.getBuckets()) {

            String timeKey = bucket.getKeyAsString();
            JSONObject jsonObject = new JSONObject();
            NumericMetricsAggregation.SingleValue totalId = (NumericMetricsAggregation.SingleValue) bucket.getAggregations().getAsMap().get("totalId");
            NumericMetricsAggregation.SingleValue totalAge = (NumericMetricsAggregation.SingleValue)bucket.getAggregations().getAsMap().get("totalAge");
            jsonObject.putIfAbsent("timeKey",timeKey);
            jsonObject.putIfAbsent("idSum",totalId.value());
            jsonObject.putIfAbsent("ageSum",totalAge.value());

            jsonList.add(jsonObject);
        }
        System.out.println("jsonList--------------"+jsonList);
        List<JSONObject> rateList = calculateValueList(jsonList);
        System.out.println("rateList======="+rateList);
        //计算百分比
        return rateList;
    }


    private List<JSONObject> calculateValueList(List<JSONObject> list) {
        List<JSONObject> rateList = new ArrayList<>();
        for(int i =0;i< list.size();i++){
            JSONObject jsonObject = new JSONObject();
            Double idSum = (Double)list.get(i).get("idSum");
            Double ageSum = (Double)list.get(i).get("ageSum");

//            Double idSum1 = (Double)list.get(i+1).get("idSum");
//            Double ageSum1 = (Double)list.get(i+1).get("ageSum");
            String idRate = getRate(idSum, ageSum);
            //String ageRate = getRate(ageSum, ageSum1);
            jsonObject.putIfAbsent("time",list.get(i).get("timeKey"));
            jsonObject.putIfAbsent("idRate",idRate);
            //jsonObject.putIfAbsent("ageRate",ageRate);
            rateList.add(jsonObject);
        }
        return rateList;
    }


    public static String getRate(Double value,Double totalSum){
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        String result = numberFormat.format((Double)value/(Double)totalSum*100);
        return result;
    }

    /**聚合条件*/
    private AggregationBuilder filterAggConditions(RingAnalysisDto ringAnalysisDto,DateHistogramInterval interval,String dimension){
        DateHistogramAggregationBuilder histogramAggregationBuilder = null;
        //时间维度
        if(Objects.nonNull(ringAnalysisDto.getTimeDimension())){
            //eg:day
            histogramAggregationBuilder = AggregationBuilders.dateHistogram((String) dimensionMap.get(ringAnalysisDto.getTimeDimension()))
                    .dateHistogramInterval(interval).field("create_time")
                    .subAggregation(AggregationBuilders.sum("totalId").field("orginal_id"))
                    .subAggregation(AggregationBuilders.sum("totalAge").field("age"));

//                    //聚合字段1
//                    .subAggregation(AggregationBuilders.sum("clickTotal").field("click"))
//                    //聚合字段2
//                    .subAggregation(AggregationBuilders.sum("sessionTotal").field("session"))
//                    //聚合字段3
//                    .subAggregation(AggregationBuilders.sum("validSessionTotal").field("validSession"))
//                    //聚合字段4
//                    .subAggregation(AggregationBuilders.sum("onlineCardTotal").field("onlineCard"));
        }
        AggregationBuilder aggregationBuilder = null;


        if(Objects.nonNull(dimension)){
            aggregationBuilder = AggregationBuilders.terms(dimensionMap.get(dimension).toString()).field(dimension)
                    //聚合字段1
                    .subAggregation(AggregationBuilders.sum("clickTotal").field("click"))
                    //聚合字段2
                    .subAggregation(AggregationBuilders.sum("sessionTotal").field("session"))
                    //聚合字段3
                    .subAggregation(AggregationBuilders.sum("validSessionTotal").field("validSession"))
                    //聚合字段4
                    .subAggregation(AggregationBuilders.sum("onlineCardTotal").field("onlineCard"));
        }
        return  histogramAggregationBuilder ==null ? aggregationBuilder: histogramAggregationBuilder;
    }

    /**条件过滤*/
    private BoolQueryBuilder filterBaseConditions(RingAnalysisDto ringAnalysisDto){
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        if(Objects.nonNull(ringAnalysisDto.getTimeRanges())){
            String[] times = ringAnalysisDto.getTimeRanges().split(",");
            boolQuery.filter(QueryBuilders.rangeQuery("过滤字段").gte(times[0]).lte(times[1]));
        }
        if(Objects.nonNull(ringAnalysisDto.getProvince())){
            boolQuery.must(QueryBuilders.termQuery("过滤字段",ringAnalysisDto.getProvince()));
        }

        if(Objects.nonNull(ringAnalysisDto.getFirstProject())){
            boolQuery.must(QueryBuilders.termQuery("过滤字段",ringAnalysisDto.getFirstProject()));
        }

        if(Objects.nonNull(ringAnalysisDto.getChannel())){
            boolQuery.must(QueryBuilders.termQuery("过滤字段",ringAnalysisDto.getChannel()));
        }

        if(Objects.nonNull(ringAnalysisDto.getPopularizeAccount())){
            boolQuery.must(QueryBuilders.termQuery("过滤字段",ringAnalysisDto.getPopularizeAccount()));
        }
        if(Objects.nonNull(ringAnalysisDto.getCarrier())){
            boolQuery.must(QueryBuilders.termQuery("过滤字段",ringAnalysisDto.getCarrier()));
        }
        if(Objects.nonNull(ringAnalysisDto.getSite())){
            boolQuery.must(QueryBuilders.termQuery("过滤字段",ringAnalysisDto.getSite()));
        }

        return boolQuery;
    }
}
原文地址:https://www.cnblogs.com/ywjfx/p/14378590.html