|
@ -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;
|
|
|
}
|
|
|
|
|
|
}
|