浏览代码

补充完善视图的聚合。

zhangjinjun 6 年之前
父节点
当前提交
b8f2e8c8d0
共有 1 个文件被更改,包括 94 次插入42 次删除
  1. 94 42
      src/main/java/com/yihu/quota/service/view/ViewService.java

+ 94 - 42
src/main/java/com/yihu/quota/service/view/ViewService.java

@ -141,17 +141,25 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
        this.joinFilters(viewBoolQueryBuilder, viewFilterModelList);
        searchRequestBuilder.setQuery(viewBoolQueryBuilder);
        // 组装聚合
        // 顶层行维度
        // 视图的顶层行维度
        List<ViewDimension> groupTopRowDimensionList = view.getGroupTopRowDimensionList();
        // 组内其他行维度
        // 视图的组内其他行维度
        Map<Integer, List<ViewDimension>> groupOtherRowDimensionsMap = view.getGroupOtherRowDimensionsMap();
        // 视图的列维度
        List<ViewDimension> colDimensionList = view.getColDimensionList();
        // 视图的指标
        List<ViewQuota> viewQuotaList = view.getViewQuotaList();
        //region 聚合组装
        if (groupTopRowDimensionList.size() == 0) {
            if (!"1".equals(view.getDisplayType())) {
                // 视图展示类型非数值场合
                throw new ApiException("请为视图至少配置一个行维度。");
            } else if (viewQuotaList == null || viewQuotaList.size() == 0) {
                throw new ApiException("请为视图至少配置一个指标。");
            } else {
                // 视图为数值展示类型的场合,没有行/列维度,直接对指标聚合。
                List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(view.getViewQuotaList());
                List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(viewQuotaList, null);
                for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                    searchRequestBuilder.addAggregation(quotaAgg);
                }
@ -164,7 +172,7 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
                String topOrderType = topRowDimension.getMemberOrderType();
                boolean isTopAsc = "asc".equals(topRowDimension.getMemberOrderStrategy()) ? true : false;
                // 有多个多维度数据集时,设定顶层聚合的数据来自哪个多维数据集。
                // 有多个多维度数据集时,设定顶层行维度聚合的数据来自哪个多维数据集。
                FilterAggregationBuilder topFilterAgg = null;
                if (indexCount > 1) {
                    String aggName = topRowDimension.getDimensionCode() + "-index-filter";
@ -178,32 +186,48 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
                AggregationBuilder topAgg = this.joinDimensionAgg(topRowDimension);
                // 遍历同组其他行维度,其聚合按顺序嵌套于同组上层行维度聚合下。
                // 遍历的上一个行维度聚合
                // 倒序遍历的上一个行维度聚合
                AggregationBuilder preRowAgg = null;
                List<ViewDimension> otherRowDimensionList = groupOtherRowDimensionsMap.get(topRowDimension.getGroupRow());
                int otherRowDimensionCount = otherRowDimensionList.size();
                for (int i = otherRowDimensionCount - 1; i > 0; i--) {
                    ViewDimension otherRowDimension = otherRowDimensionList.get(i);
                    AggregationBuilder rowAgg = this.joinDimensionAgg(otherRowDimension);
                    if (i == otherRowDimensionCount - 1) {
                        // 遍历组装列维度的聚合
                        List<ViewDimension> calDimensionList = view.getColDimensionList();
                        for (ViewDimension colDimension : calDimensionList) {
                            AggregationBuilder calAgg = this.joinDimensionAgg(colDimension);
                            // 遍历组装指标的聚合
                            List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(view.getViewQuotaList());
                            for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                                calAgg.subAggregation(quotaAgg);
                if (otherRowDimensionList != null && otherRowDimensionList.size() > 0) {
                    int otherRowDimensionCount = otherRowDimensionList.size();
                    for (int i = otherRowDimensionCount - 1; i > 0; i--) {
                        ViewDimension otherRowDimension = otherRowDimensionList.get(i);
                        AggregationBuilder rowAgg = this.joinDimensionAgg(otherRowDimension);
                        // 末端行维度场合
                        if (i == otherRowDimensionCount - 1) {
                            // 组装列维度的聚合
                            if (colDimensionList != null && colDimensionList.size() != 0) {
                                for (ViewDimension colDimension : colDimensionList) {
                                    AggregationBuilder calAgg = this.joinDimensionAgg(colDimension);
                                    // 在列维度聚合上,嵌套指标的聚合
                                    List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(viewQuotaList, colDimension);
                                    for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                                        calAgg.subAggregation(quotaAgg);
                                    }
                                    rowAgg.subAggregation(calAgg);
                                }
                            } else {
                                // 没有列维度的场合,在末端行维度聚合上,嵌套指标的聚合
                                List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(viewQuotaList, otherRowDimension);
                                for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                                    rowAgg.subAggregation(quotaAgg);
                                }
                            }
                            rowAgg.subAggregation(calAgg);
                            preRowAgg = rowAgg;
                        } else {
                            rowAgg.subAggregation(preRowAgg);
                            preRowAgg = rowAgg;
                        }
                        preRowAgg = rowAgg;
                    } else {
                        rowAgg.subAggregation(preRowAgg);
                        preRowAgg = rowAgg;
                        topAgg.subAggregation(rowAgg);
                    }
                } else {
                    // 行维度组内只有一个行维度的场合,在顶层行维度聚合上,嵌套指标的聚合
                    List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(viewQuotaList, topRowDimension);
                    for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                        topAgg.subAggregation(quotaAgg);
                    }
                }
@ -215,6 +239,7 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
                }
            }
        }
        //endregion 聚合组装
        SearchResponse searchResponse = searchRequestBuilder.get();
        Aggregations aggregations = searchResponse.getAggregations();
@ -298,41 +323,49 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
     * 汇总指标的度量聚合
     *
     * @param viewQuotaList 视图的指标
     * @param viewDimension 视图的行/列维度
     * @return 指标的度量聚合
     * @throws IOException
     */
    private List<AbstractAggregationBuilder> gatherQuotaMetricsAgg(List<ViewQuota> viewQuotaList) throws IOException {
    private List<AbstractAggregationBuilder> gatherQuotaMetricsAgg(List<ViewQuota> viewQuotaList, ViewDimension viewDimension) throws IOException {
        String aggNamePre = "";
        if (viewDimension != null) {
            String dimensionCode = viewDimension.getDimensionCode();
            // TODO 合计 二字需要替换成固定的编码
            aggNamePre = "合计".equals(dimensionCode) ? dimensionCode + "-" : "";
        }
        List<AbstractAggregationBuilder> quotaAggList = new ArrayList<>();
        for (ViewQuota quota : viewQuotaList) {
            if ("basic".equals(quota.getFormulaMode())) {
                if ("sum".equals(quota.getBasicFormulaType())) {
                    // 求和
                    String aggName = "sum-result";
                    String aggName = aggNamePre + "sum-result";
                    SumBuilder sumAgg = AggregationBuilders.sum(aggName).field(quota.getDimensionCode());
                    quotaAggList.add(this.joinMetricAgg(sumAgg, quota));
                } else if ("count".equals(quota.getBasicFormulaType())) {
                    // 计数
                    String aggName = "count-result";
                    String aggName = aggNamePre + "count-result";
                    ValueCountBuilder countAgg = AggregationBuilders.count(aggName).field(quota.getDimensionCode());
                    quotaAggList.add(this.joinMetricAgg(countAgg, quota));
                } else if ("avg".equals(quota.getBasicFormulaType())) {
                    // 均值
                    String aggName = "avg-result";
                    String aggName = aggNamePre + "avg-result";
                    AvgBuilder avgAgg = AggregationBuilders.avg(aggName).field(quota.getDimensionCode());
                    quotaAggList.add(this.joinMetricAgg(avgAgg, quota));
                } else if ("max".equals(quota.getBasicFormulaType())) {
                    // 最大值
                    String aggName = "max-result";
                    String aggName = aggNamePre + "max-result";
                    MaxBuilder maxAgg = AggregationBuilders.max(aggName).field(quota.getDimensionCode());
                    quotaAggList.add(this.joinMetricAgg(maxAgg, quota));
                } else if ("min".equals(quota.getBasicFormulaType())) {
                    // 最小值
                    String aggName = "min-result";
                    String aggName = aggNamePre + "min-result";
                    MinBuilder minAgg = AggregationBuilders.min(aggName).field(quota.getDimensionCode());
                    quotaAggList.add(this.joinMetricAgg(minAgg, quota));
                } else if ("cardinality".equals(quota.getBasicFormulaType())) {
                    // 去重计数
                    String aggName = "cardinality-result";
                    String aggName = aggNamePre + "cardinality-result";
                    CardinalityBuilder cardinalityAgg = AggregationBuilders.cardinality(aggName).field(quota.getDimensionCode());
                    quotaAggList.add(this.joinMetricAgg(cardinalityAgg, quota));
                }
@ -391,8 +424,17 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
            if (StringUtils.isEmpty(orderType) || "name".equals(orderType)) {
                ((TermsBuilder) dimensionAgg).order(Terms.Order.term(isTopAsc));
            } else {
                // TODO 按子聚合结果排序,需拼接子聚合名称
                ((TermsBuilder) dimensionAgg).order(Terms.Order.aggregation("", isTopAsc));
                // 按子聚合结果排序,拼接子聚合路径
                String memberOrderQuotaId = viewDimension.getMemberOrderQuotaId();
                if (StringUtils.isNotEmpty(memberOrderQuotaId)) {
                    ViewQuota viewQuota = viewQuotaDao.findOne(memberOrderQuotaId);
                    if ("basic".equals(viewQuota.getFormulaMode())) {
                        String subAggPath = viewQuota.getBasicFormulaType() + "-result";
                        ((TermsBuilder) dimensionAgg).order(Terms.Order.aggregation(subAggPath, isTopAsc));
                    } else {
                        ((TermsBuilder) dimensionAgg).order(Terms.Order.term(isTopAsc));
                    }
                }
            }
            // 设置分组个数
@ -404,20 +446,30 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
                ((TermsBuilder) dimensionAgg).size(1000);
            }
        } else {
            String aggName = viewDimension + "-date_histogram";
            String aggName = dimensionCode + "-date_histogram";
            dimensionAgg = AggregationBuilders.dateHistogram(aggName).field(dimensionCode);
            ((DateHistogramBuilder) dimensionAgg).minDocCount(0);
            ((DateHistogramBuilder) dimensionAgg).format(viewDimension.getMemberDateFormat());
            ((DateHistogramBuilder) dimensionAgg).interval(new DateHistogramInterval(viewDimension.getMemberDateInterval()));
            // 设置排序
            Histogram.Order order = isTopAsc ? Histogram.Order.KEY_ASC : Histogram.Order.KEY_DESC;
            if (StringUtils.isEmpty(orderType) || "name".equals(orderType)) {
                Histogram.Order order = isTopAsc ? Histogram.Order.KEY_ASC : Histogram.Order.KEY_DESC;
                ((DateHistogramBuilder) dimensionAgg).order(order);
            } else {
                // TODO 按子聚合结果排序,需拼接子聚合名称
                ((DateHistogramBuilder) dimensionAgg).order(Histogram.Order.aggregation("", isTopAsc));
                // 按子聚合结果排序,拼接子聚合路径
                String memberOrderQuotaId = viewDimension.getMemberOrderQuotaId();
                if (StringUtils.isNotEmpty(memberOrderQuotaId)) {
                    ViewQuota viewQuota = viewQuotaDao.findOne(memberOrderQuotaId);
                    if ("basic".equals(viewQuota.getFormulaMode())) {
                        String subAggPath = viewQuota.getBasicFormulaType() + "-result";
                        ((DateHistogramBuilder) dimensionAgg).order(Histogram.Order.aggregation(subAggPath, isTopAsc));
                    } else {
                        ((DateHistogramBuilder) dimensionAgg).order(order);
                    }
                }
            }
            // TODO 需动态根据条件范围设置,或设置默认值
            ((DateHistogramBuilder) dimensionAgg).extendedBounds("", "");
            // TODO 动态根据条件范围设置,或设置默认值
//            ((DateHistogramBuilder) dimensionAgg).extendedBounds("", "");
        }
        return dimensionAgg;