Browse Source

大体完成将视图规则封装生成ES聚合语法。还需补充完善部分点。

zhangjinjun 6 years ago
parent
commit
710ba341cd
1 changed files with 105 additions and 63 deletions
  1. 105 63
      src/main/java/com/yihu/quota/service/view/ViewService.java

+ 105 - 63
src/main/java/com/yihu/quota/service/view/ViewService.java

@ -27,6 +27,7 @@ import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
@ -150,7 +151,10 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
                throw new ApiException("请为视图至少配置一个行维度。");
            } else {
                // 视图为数值展示类型的场合,没有行/列维度,直接对指标聚合。
                this.gatherMetricsAgg(searchRequestBuilder, view.getViewQuotaList());
                List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(view.getViewQuotaList());
                for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                    searchRequestBuilder.addAggregation(quotaAgg);
                }
            }
        } else {
            int indexCount = esIndices.length;
@ -171,60 +175,44 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
                // TODO 当顶层行维度是合计维度时,合计维度与列维度组合的聚合都在聚合节点顶层。
                // 顶层行维度聚合
                AggregationBuilder topAgg = null;
                String fieldType = cubeService.findDimensionDataType(topRowDimension.getCubeCode(), topRowDimension.getDimensionCode());
                if (!"date".equals(fieldType)) {
                    String aggName = topRowDimensionCode + "-terms";
                    topAgg = AggregationBuilders.terms(aggName).field(topRowDimensionCode);
                    // 设置排序
                    if (StringUtils.isEmpty(topOrderType) || "name".equals(topOrderType)) {
                        ((TermsBuilder) topAgg).order(Terms.Order.term(isTopAsc));
                    } else {
                        // TODO 按子聚合结果排序,需拼接子聚合名称
                        ((TermsBuilder) topAgg).order(Terms.Order.aggregation("", isTopAsc));
                    }
                    // 设置分组个数
                    int memberCount = topRowDimension.getMemberCount();
                    if (memberCount > 0) {
                        ((TermsBuilder) topAgg).size(memberCount);
                    } else {
                        // TODO 动态获取全部的分组个数进行设置
                        ((TermsBuilder) topAgg).size(1000);
                    }
                } else {
                    String aggName = topRowDimensionCode + "-date_histogram";
                    topAgg = AggregationBuilders.dateHistogram(aggName).field(topRowDimensionCode);
                    ((DateHistogramBuilder) topAgg).minDocCount(0);
                    ((DateHistogramBuilder) topAgg).format(topRowDimension.getMemberDateFormat());
                    ((DateHistogramBuilder) topAgg).interval(new DateHistogramInterval(topRowDimension.getMemberDateInterval()));
                    if (StringUtils.isEmpty(topOrderType) || "name".equals(topOrderType)) {
                        Histogram.Order order = isTopAsc ? Histogram.Order.KEY_ASC : Histogram.Order.KEY_DESC;
                        ((DateHistogramBuilder) topAgg).order(order);
                    } else {
                        // TODO 按子聚合结果排序,需拼接子聚合名称
                        ((DateHistogramBuilder) topAgg).order(Histogram.Order.aggregation("", isTopAsc));
                    }
                    // TODO 需动态根据条件范围设置,或设置默认值
                    ((DateHistogramBuilder) topAgg).extendedBounds("", "");
                }
                AggregationBuilder topAgg = this.joinDimensionAgg(topRowDimension);
                // 遍历同组其他行维度,其聚合按顺序嵌套于同组上层行维度聚合下。
                AggregationBuilder secondRowAgg = null; // 第二个行维度聚合
                AggregationBuilder lastRowAgg = null; // 最后一个行维度聚合
                // 遍历的上一个行维度聚合
                AggregationBuilder preRowAgg = null;
                List<ViewDimension> otherRowDimensionList = groupOtherRowDimensionsMap.get(topRowDimension.getGroupRow());
                int otherRowDimensionCount = otherRowDimensionList.size();
                for (int i = 0; i < otherRowDimensionCount; i++) {
                for (int i = otherRowDimensionCount - 1; i > 0; i--) {
                    ViewDimension otherRowDimension = otherRowDimensionList.get(i);
                    String otherRowDimensionCode = otherRowDimension.getDimensionCode();
                    AggregationBuilder rowAgg = this.joinDimensionAgg(otherRowDimension);
                    if (i == otherRowDimensionCount - 1) {
                        // 遍历组装列维度的聚合
                        List<ViewDimension> calDimensionList = view.getColDimensionList();
                        for (ViewDimension colDimension : calDimensionList) {
                            AggregationBuilder calAgg = this.joinDimensionAgg(colDimension);
                    ViewDimension nextOtherRowDimension = null;
                    if (i < otherRowDimensionCount - 1) {
                        nextOtherRowDimension = otherRowDimensionList.get(i + 1);
                            // 遍历组装指标的聚合
                            List<AbstractAggregationBuilder> quotaAggList = this.gatherQuotaMetricsAgg(view.getViewQuotaList());
                            for (AbstractAggregationBuilder quotaAgg : quotaAggList) {
                                calAgg.subAggregation(quotaAgg);
                            }
                            rowAgg.subAggregation(calAgg);
                        }
                        preRowAgg = rowAgg;
                    } else {
                        rowAgg.subAggregation(preRowAgg);
                        preRowAgg = rowAgg;
                    }
                }
                if (topFilterAgg != null) {
                    topFilterAgg.subAggregation(topAgg);
                    searchRequestBuilder.addAggregation(topFilterAgg);
                } else {
                    searchRequestBuilder.addAggregation(topAgg);
                }
            }
        }
@ -307,59 +295,60 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
    }
    /**
     * 汇总视图为数值展示类型的各种度量聚合
     * 汇总指标的度量聚合
     *
     * @param searchRequestBuilder ES请求构建器
     * @param viewQuotaList        视图的指标
     * @param viewQuotaList 视图的指标
     * @return 指标的度量聚合
     * @throws IOException
     */
    private void gatherMetricsAgg(SearchRequestBuilder searchRequestBuilder, List<ViewQuota> viewQuotaList) throws IOException {
    private List<AbstractAggregationBuilder> gatherQuotaMetricsAgg(List<ViewQuota> viewQuotaList) throws IOException {
        List<AbstractAggregationBuilder> quotaAggList = new ArrayList<>();
        for (ViewQuota quota : viewQuotaList) {
            if ("basic".equals(quota.getFormulaMode())) {
                if ("sum".equals(quota.getBasicFormulaType())) {
                    // 求和
                    String aggName = "sum-result";
                    SumBuilder sumAgg = AggregationBuilders.sum(aggName).field(quota.getDimensionCode());
                    this.joinMetricAgg(searchRequestBuilder, sumAgg, quota);
                    quotaAggList.add(this.joinMetricAgg(sumAgg, quota));
                } else if ("count".equals(quota.getBasicFormulaType())) {
                    // 计数
                    String aggName = "count-result";
                    ValueCountBuilder countAgg = AggregationBuilders.count(aggName).field(quota.getDimensionCode());
                    this.joinMetricAgg(searchRequestBuilder, countAgg, quota);
                    quotaAggList.add(this.joinMetricAgg(countAgg, quota));
                } else if ("avg".equals(quota.getBasicFormulaType())) {
                    // 均值
                    String aggName = "avg-result";
                    AvgBuilder avgAgg = AggregationBuilders.avg(aggName).field(quota.getDimensionCode());
                    this.joinMetricAgg(searchRequestBuilder, avgAgg, quota);
                    quotaAggList.add(this.joinMetricAgg(avgAgg, quota));
                } else if ("max".equals(quota.getBasicFormulaType())) {
                    // 最大值
                    String aggName = "max-result";
                    MaxBuilder maxAgg = AggregationBuilders.max(aggName).field(quota.getDimensionCode());
                    this.joinMetricAgg(searchRequestBuilder, maxAgg, quota);
                    quotaAggList.add(this.joinMetricAgg(maxAgg, quota));
                } else if ("min".equals(quota.getBasicFormulaType())) {
                    // 最小值
                    String aggName = "min-result";
                    MinBuilder minAgg = AggregationBuilders.min(aggName).field(quota.getDimensionCode());
                    this.joinMetricAgg(searchRequestBuilder, minAgg, quota);
                    quotaAggList.add(this.joinMetricAgg(minAgg, quota));
                } else if ("cardinality".equals(quota.getBasicFormulaType())) {
                    // 去重计数
                    String aggName = "cardinality-result";
                    CardinalityBuilder cardinalityAgg = AggregationBuilders.cardinality(aggName).field(quota.getDimensionCode());
                    this.joinMetricAgg(searchRequestBuilder, cardinalityAgg, quota);
                    quotaAggList.add(this.joinMetricAgg(cardinalityAgg, quota));
                }
            }
        }
        return quotaAggList;
    }
    /**
     * 组装视图为数值展示类型的聚合
     * 组装度量聚合
     *
     * @param searchRequestBuilder ES请求构建器
     * @param metricAgg            ES度量聚合构建器
     * @param quota                视图指标
     * @param metricAgg ES度量聚合构建器
     * @param quota     视图指标
     * @throws IOException
     */
    private void joinMetricAgg(SearchRequestBuilder searchRequestBuilder, MetricsAggregationBuilder metricAgg, ViewQuota quota) throws IOException {
    private AbstractAggregationBuilder joinMetricAgg(MetricsAggregationBuilder metricAgg, ViewQuota quota) throws IOException {
        List<ViewQuotaFilter> quotaFilterList = quota.getQuotaFilterList();
        FilterAggregationBuilder filterAgg = null;
        if (quotaFilterList != null && quotaFilterList.size() > 0) {
@ -375,10 +364,63 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
        }
        if (filterAgg == null) {
            searchRequestBuilder.addAggregation(metricAgg);
            return metricAgg;
        } else {
            return filterAgg;
        }
    }
    /**
     * 组装行/列维度的聚合
     *
     * @param viewDimension 视图行/列维度
     * @return 行/列维度的聚合
     */
    private AggregationBuilder joinDimensionAgg(ViewDimension viewDimension) {
        AggregationBuilder dimensionAgg = null;
        String dimensionCode = viewDimension.getDimensionCode();
        String orderType = viewDimension.getMemberOrderType();
        boolean isTopAsc = "asc".equals(viewDimension.getMemberOrderStrategy()) ? true : false;
        String fieldType = cubeService.findDimensionDataType(viewDimension.getCubeCode(), viewDimension.getDimensionCode());
        if (!"date".equals(fieldType)) {
            String aggName = dimensionCode + "-terms";
            dimensionAgg = AggregationBuilders.terms(aggName).field(dimensionCode);
            // 设置排序
            if (StringUtils.isEmpty(orderType) || "name".equals(orderType)) {
                ((TermsBuilder) dimensionAgg).order(Terms.Order.term(isTopAsc));
            } else {
                // TODO 按子聚合结果排序,需拼接子聚合名称
                ((TermsBuilder) dimensionAgg).order(Terms.Order.aggregation("", isTopAsc));
            }
            // 设置分组个数
            int memberCount = viewDimension.getMemberCount();
            if (memberCount > 0) {
                ((TermsBuilder) dimensionAgg).size(memberCount);
            } else {
                // TODO 需动态获取全部的分组个数进行设置
                ((TermsBuilder) dimensionAgg).size(1000);
            }
        } else {
            searchRequestBuilder.addAggregation(filterAgg);
            String aggName = viewDimension + "-date_histogram";
            dimensionAgg = AggregationBuilders.dateHistogram(aggName).field(dimensionCode);
            ((DateHistogramBuilder) dimensionAgg).minDocCount(0);
            ((DateHistogramBuilder) dimensionAgg).format(viewDimension.getMemberDateFormat());
            ((DateHistogramBuilder) dimensionAgg).interval(new DateHistogramInterval(viewDimension.getMemberDateInterval()));
            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));
            }
            // TODO 需动态根据条件范围设置,或设置默认值
            ((DateHistogramBuilder) dimensionAgg).extendedBounds("", "");
        }
        return dimensionAgg;
    }
}