Forráskód Böngészése

修改实体类字段、注释;组装视图的聚合。

zhangjinjun 6 éve
szülő
commit
65bbbb4044

+ 24 - 73
src/main/java/com/yihu/quota/controller/ViewController.java

@ -1,47 +1,40 @@
package com.yihu.quota.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.util.rest.Envelop;
import com.yihu.quota.model.cube.Cube;
import com.yihu.quota.model.view.View;
import com.yihu.quota.model.view.ViewDimension;
import com.yihu.quota.model.view.ViewQuota;
import com.yihu.quota.service.cube.CubeService;
import com.yihu.quota.service.view.ViewDimensionService;
import com.yihu.quota.service.view.ViewQuotaService;
import com.yihu.quota.service.view.ViewService;
import com.yihu.quota.util.AggregationBuildHandler;
import com.yihu.quota.util.ElasticSearchHandler;
import com.yihu.quota.vo.ViewQuotaFilterModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
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.bucket.terms.TermsBuilder;
import org.elasticsearch.search.aggregations.metrics.MetricsAggregationBuilder;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * @author janseny
 * @date 2018年9月26日
 */
@RestController
@RequestMapping(ApiVersion.Version1_0 )
@RequestMapping(ApiVersion.Version1_0)
@Api(description = "OLAP 视图 控制入口")
public class ViewController extends BaseController {
public class ViewController extends EnvelopRestEndPoint {
    @Autowired
    private ViewService viewService;
@ -53,8 +46,6 @@ public class ViewController extends BaseController {
    private ViewQuotaService viewQuotaService;
    @Autowired
    private ElasticSearchHandler elasticSearchHandler;
    @Autowired
    private AggregationBuildHandler aggregationBuildHandler;
    @ApiOperation(value = "添加视图")
    @RequestMapping(value = ServiceApi.StatisticView.View.Add, method = RequestMethod.GET)
@ -70,7 +61,7 @@ public class ViewController extends BaseController {
            @ApiParam(name = "isDrill", value = "可钻取 1:可以,2:不可以", required = false)
            @RequestParam(value = "isDrill", required = false) String isDrill
    ){
    ) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(true);
        try {
@ -83,7 +74,7 @@ public class ViewController extends BaseController {
            view.setDisplayType(displayType != null ? displayType : "1");
            view.setIsDrill(isDrill != null ? isDrill : "1");
            viewService.save(view);
        }catch (Exception e){
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setSuccessFlg(false);
        }
@ -94,7 +85,7 @@ public class ViewController extends BaseController {
    @RequestMapping(value = ServiceApi.StatisticView.View.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "ID", required = true)
            @RequestParam(value = "id", required = true) int id){
            @RequestParam(value = "id", required = true) int id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(true);
        viewService.delete(id);
@ -106,70 +97,30 @@ public class ViewController extends BaseController {
    public Envelop getViewStatisticData(
            @ApiParam(name = "viewCode", value = "视图编码", required = true)
            @RequestParam(value = "viewCode") String viewCode,
            @ApiParam(name = "filters", value = "过滤条件JSON字符串,如:'[{\"relationType\":\"and\",\"field\":\"event_date\",\"compareType\":\">=\",\"filterValue\":\"2017-06-11\"}]'")
            @ApiParam(name = "filters", value = "过滤条件JSON字符串,如:'[{\"relationType\":\"and\",\"field\":\"event_date\",\"compareType\":\"belong\",\"filterValue\":\"2017-06-11\"}]'")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sort", value = "排序JSON字符串,如:'{\"field\":\"event_date\",\"type\":\"asc\"}'")
            @RequestParam(value = "sort", required = false) String sort) {
            @ApiParam(name = "sort", value = "排序JSON字符串,排序字段从可排序的维度中挑选,如:'{\"field\":\"event_date\",\"type\":\"asc\"}'")
            @RequestParam(value = "sort", required = false) String sort,
            @ApiParam(name = "drillDimension", value = "钻取维度编码,如:'{\"field\":\"event_date\"}'")
            @RequestParam(value = "drillDimension", required = false) String drillDimension) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(true);
        try {
            // 根据视图规则,获取统计结果
            viewService.statViewResult(viewCode, filters);
            // 将统计结果,转换成展示的数据格式
            // TODO
        }catch (Exception e){
            e.printStackTrace();
            envelop.setSuccessFlg(false);
        }
        return envelop;
    }
    /**
     * 例5:展示2017年区县、性别的就诊人次数,以及合计。
     * @return
     */
    @ApiOperation(value = "Test 例五 二维表")
    @RequestMapping(value = "/test5", method = RequestMethod.DELETE)
    public Envelop test5(){
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(true);
        try {
            BoolQueryBuilder boolQueryBuilder = null;
//            RangeQueryBuilder rangeQueryStartTime = QueryBuilders.rangeQuery("quotaDate").gte("2017-01-01");
//            boolQueryBuilder.must(rangeQueryStartTime);
//            RangeQueryBuilder rangeQueryEndTime = QueryBuilders.rangeQuery("quotaDate").lte("2017-12-31");
//            boolQueryBuilder.must(rangeQueryEndTime);
            List<ViewQuotaFilterModel> filterModelList = new ArrayList<>();
            if (StringUtils.isNotEmpty(filters)) {
                filterModelList = objectMapper.readValue(filters, new TypeReference<List<ViewQuotaFilterModel>>() {
                });
            }
            Aggregations aggregations = viewService.statViewResult(viewCode, filterModelList);
            TransportClient client = elasticSearchHandler.getTransportClient();
//            ValueCountBuilder firstAgg = AggregationBuilders.count("count_result").field("rowkey");
//            TermsBuilder secondAgg = AggregationBuilders.terms("合计_性别_terms").field("sex")
//                    .subAggregation(AggregationBuilders.count("count_result").field("rowkey"));
//            TermsBuilder threeAgg = AggregationBuilders.terms("区县_terms").field("area.town")
//                    .subAggregation(AggregationBuilders.count("合计_count_result").field("rowkey"))
//                    .subAggregation(AggregationBuilders.terms("性别_terms").field("sex")
//                                    .subAggregation(AggregationBuilders.count("count_result").field("rowkey"))
//                    );
            AbstractAggregationBuilder firstAgg = aggregationBuildHandler.addAggregationBuilder("count","count_result","rowkey");
            AbstractAggregationBuilder secondAgg = aggregationBuildHandler.addTermAggregationBuilder("合计_性别_terms","sex","count", "count_result", "rowkey");
            AbstractAggregationBuilder threeAgg = aggregationBuildHandler.addTermsBuilder("区县_terms", "area.town")
                    .subAggregation(aggregationBuildHandler.addAggregationBuilder("count", "合计_count_result", "rowkey"))
                    .subAggregation(aggregationBuildHandler.addTermsBuilder("性别_terms","sex")
                                    .subAggregation(aggregationBuildHandler.addAggregationBuilder("count", "count_result", "rowkey"))
                    );
            // TODO 将统计结果转换成展示的数据格式
            LinkedList<AbstractAggregationBuilder> aggBuildList = new LinkedList<>();
            aggBuildList.add(firstAgg);
            aggBuildList.add(secondAgg);
            aggBuildList.add(threeAgg);
            List<Map<String, Object>> resultList = aggregationBuildHandler.structAggregationQuery(client,"patient_event","info", boolQueryBuilder, aggBuildList);
            envelop.setDetailModelList(resultList);
        }catch (Exception e){
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setSuccessFlg(false);
        }
        return envelop;
    }
}

+ 18 - 17
src/main/java/com/yihu/quota/controller/ViewDimensionController.java

@ -1,6 +1,8 @@
package com.yihu.quota.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.util.rest.Envelop;
import com.yihu.quota.model.view.View;
import com.yihu.quota.model.view.ViewDimension;
@ -20,9 +22,9 @@ import org.springframework.web.bind.annotation.RestController;
 * @date 2018年9月26日
 */
@RestController
@RequestMapping(ApiVersion.Version1_0 + "/viewDimension")
@RequestMapping(ApiVersion.Version1_0)
@Api(description = "OLAP 视图维度 控制入口")
public class ViewDimensionController extends BaseController {
public class ViewDimensionController extends EnvelopRestEndPoint {
    @Autowired
    private ViewDimensionService viewDimensionService;
@ -30,24 +32,24 @@ public class ViewDimensionController extends BaseController {
    private ViewService viewService;
    @ApiOperation(value = "添加视图维度")
    @RequestMapping(value = "/addViewDimension", method = RequestMethod.GET)
    @RequestMapping(value = ServiceApi.StatisticView.ViewQuota.Add, method = RequestMethod.GET)
    public Envelop addViewDimension(
            @ApiParam(name = "code", value = "维度code", required = true)
            @RequestParam(value = "code", required = true) String code,
            @ApiParam(name = "name", value = "维度名称", required = true)
            @RequestParam(value = "name", required = true) String name,
            @ApiParam(name = "viewId", value = "多维数据集ID", required = true)
            @RequestParam(value = "viewId", required = true) int viewId,
            @ApiParam(name = "rankType", value = "1:行维度,2,:列维度,默认行维度", required = false)
            @RequestParam(value = "rankType", required = false) String rankType,
            @RequestParam(value = "viewId", required = true) String viewId,
            @ApiParam(name = "dimensionType", value = "维度类型,row:行维度,col:列维度,drill:钻取维度", required = false)
            @RequestParam(value = "dimensionType", required = false) String dimensionType,
            @ApiParam(name = "groupRow", value = "行维度组", required = false)
            @RequestParam(value = "groupRow", required = true) int groupRow,
            @ApiParam(name = "groupRowOrder", value = "组内行维度顺序", required = false)
            @RequestParam(value = "groupRowOrder", required = false) int groupRowOrder,
            @ApiParam(name = "columnOrder", value = "列维度顺序", required = false)
            @RequestParam(value = "columnOrder", required = false) int columnOrder,
            @ApiParam(name = "rowMemberorderType", value = "行维度成员排序方式,1:按名称排序,2:按子聚合统计值排序,默认按名称排序。", required = false)
            @RequestParam(value = "rowMemberorderType", required = false) String rowMemberorderType,
            @ApiParam(name = "columnDrillOrder", value = "列维度/钻取维度的顺序", required = false)
            @RequestParam(value = "columnDrillOrder", required = false) int columnDrillOrder,
            @ApiParam(name = "rowMemberOrderType", value = "行维度成员排序方式,name:按名称排序,sub_agg:按子聚合统计值排序", required = false)
            @RequestParam(value = "rowMemberOrderType", required = false) String rowMemberOrderType,
            @ApiParam(name = "rowMemberCount", value = "行维度成员返回个数", required = false)
            @RequestParam(value = "rowMemberCount", required = false) int rowMemberCount
    ){
@ -59,14 +61,13 @@ public class ViewDimensionController extends BaseController {
            viewDimension.setViewId(viewId);
            viewDimension.setDimensionCode(code);
            viewDimension.setDimensionName(name);
            String dataset = view.getDimensionDataset();
            viewDimension.setEsIndex(dataset.substring(0,dataset.indexOf("/")));
            viewDimension.setEsIndex(dataset.substring(dataset.indexOf("/")+1));
            viewDimension.setRankType(rankType);
            viewDimension.setEsIndex(view.getEsIndex());
            viewDimension.setEsIndex(view.getEsType());
            viewDimension.setDimensionType(dimensionType);
            viewDimension.setGroupRow(groupRow);
            viewDimension.setGroupRowOrder(groupRowOrder);
            viewDimension.setColumnOrder(columnOrder);
            viewDimension.setRowMemberOrderType(rowMemberorderType);
            viewDimension.setColumnDrillOrder(columnDrillOrder);
            viewDimension.setRowMemberOrderType(rowMemberOrderType);
            viewDimension.setRowMemberCount(rowMemberCount);
            viewDimensionService.save(viewDimension);
        }catch (Exception e){
@ -77,7 +78,7 @@ public class ViewDimensionController extends BaseController {
    }
    @ApiOperation(value = "删除视图维度")
    @RequestMapping(value = "/delViewDimension", method = RequestMethod.DELETE)
    @RequestMapping(value = ServiceApi.StatisticView.ViewQuota.Delete, method = RequestMethod.DELETE)
    public Envelop delViewDimension(
            @ApiParam(name = "id", value = "ID", required = true)
            @RequestParam(value = "id", required = true) int id){

+ 12 - 11
src/main/java/com/yihu/quota/controller/ViewQuotaController.java

@ -1,6 +1,8 @@
package com.yihu.quota.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.util.rest.Envelop;
import com.yihu.quota.model.cube.Cube;
import com.yihu.quota.model.view.View;
@ -22,9 +24,9 @@ import org.springframework.web.bind.annotation.RestController;
 * @date 2018年9月26日
 */
@RestController
@RequestMapping(ApiVersion.Version1_0 + "/viewQuota")
@RequestMapping(ApiVersion.Version1_0)
@Api(description = "OLAP 视图指标 控制入口")
public class ViewQuotaController extends BaseController {
public class ViewQuotaController extends EnvelopRestEndPoint {
    @Autowired
    private ViewQuotaService viewQuotaService;
@ -32,19 +34,19 @@ public class ViewQuotaController extends BaseController {
    private ViewService viewService;
    @ApiOperation(value = "添加视图指标")
    @RequestMapping(value = "/addViewQuota", method = RequestMethod.GET)
    @RequestMapping(value = ServiceApi.StatisticView.ViewQuota.Add, method = RequestMethod.GET)
    public Envelop addViewQuota(
            @ApiParam(name = "code", value = "维度code", required = true)
            @RequestParam(value = "code", required = true) String code,
            @ApiParam(name = "name", value = "维度名称", required = true)
            @RequestParam(value = "name", required = true) String name,
            @ApiParam(name = "viewId", value = "多维数据集ID", required = true)
            @RequestParam(value = "viewId", required = true) int viewId,
            @ApiParam(name = "formulaMode", value = "计算方式,1:基础公式,2:自定义公式。", required = true)
            @RequestParam(value = "viewId", required = true) String viewId,
            @ApiParam(name = "formulaMode", value = "计算方式,basic:基础公式,custom:自定义公式", required = true)
            @RequestParam(value = "formulaMode", required = false) String formulaMode,
            @ApiParam(name = "basicFormulaType", value = "基础公式:1:求和,2.计数,3:均值,4:最大值,5:最小值,6:去重计数", required = false)
            @ApiParam(name = "basicFormulaType", value = "基础公式:sum:求和,count.计数,avg:均值,max:最大值,min:最小值,cardinality:去重计数", required = false)
            @RequestParam(value = "basicFormulaType", required = false) String basicFormulaType,
            @ApiParam(name = "chartType", value = "图表类型,1:折线图,2:柱状图。", required = false)
            @ApiParam(name = "chartType", value = "图表类型,line:折线图,bar:柱状图", required = false)
            @RequestParam(value = "chartType", required = false) String chartType
    ){
        Envelop envelop = new Envelop();
@ -55,9 +57,8 @@ public class ViewQuotaController extends BaseController {
            viewQuota.setViewId(viewId);
            viewQuota.setDimensionCode(code);
            viewQuota.setDimensionName(name);
            String dataset = view.getDimensionDataset();
            viewQuota.setEsIndex(dataset.substring(0, dataset.indexOf("/")));
            viewQuota.setEsIndex(dataset.substring(dataset.indexOf("/") + 1));
            viewQuota.setEsIndex(view.getEsIndex());
            viewQuota.setEsIndex(view.getEsType());
            viewQuota.setFormulaMode(formulaMode);
            viewQuota.setBasicFormulaType(basicFormulaType);
            viewQuota.setChartType(chartType);
@ -70,7 +71,7 @@ public class ViewQuotaController extends BaseController {
    }
    @ApiOperation(value = "删除视图指标")
    @RequestMapping(value = "/delViewQuota", method = RequestMethod.DELETE)
    @RequestMapping(value = ServiceApi.StatisticView.ViewQuota.Delete, method = RequestMethod.DELETE)
    public Envelop delViewQuota(
            @ApiParam(name = "id", value = "ID", required = true)
            @RequestParam(value = "id", required = true) int id){

+ 3 - 1
src/main/java/com/yihu/quota/dao/view/ViewDao.java

@ -6,10 +6,12 @@ import org.springframework.data.repository.query.Param;
/**
 * 视图 DAO
 *
 * @author janseny
 * @date 2018年9月26日
 */
public interface ViewDao extends PagingAndSortingRepository<View, Integer> {
public interface ViewDao extends PagingAndSortingRepository<View, String> {
    View findByCode(@Param("code") String code);

+ 31 - 2
src/main/java/com/yihu/quota/dao/view/ViewDimensionDao.java

@ -1,6 +1,7 @@
package com.yihu.quota.dao.view;
import com.yihu.quota.model.view.ViewDimension;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
@ -8,11 +9,39 @@ import java.util.List;
/**
 * 视图维度 DAO
 *
 * @author janseny
 * @date 2018年9月26日
 */
public interface ViewDimensionDao extends PagingAndSortingRepository<ViewDimension, Integer> {
public interface ViewDimensionDao extends PagingAndSortingRepository<ViewDimension, String> {
    List<ViewDimension> findByViewId(@Param("viewId") String viewId);
    /**
     * 获取各组组内的顶层行维度
     *
     * @param viewId
     * @return
     */
    @Query(" FROM ViewDimension WHERE viewId = :viewId AND dimensionType = 'row' AND groupRowOrder = 1 ORDER BY groupRow ASC ")
    List<ViewDimension> getGroupTopRowDimensionList(@Param("viewId") String viewId);
    /**
     * 获取组内的其他行维度
     *
     * @param viewId
     * @param groupRow
     * @return
     */
    @Query(" FROM ViewDimension WHERE viewId = :viewId AND dimensionType = 'row' AND groupRowOrder <> 1 ORDER BY groupRowOrder ASC ")
    List<ViewDimension> getGroupOtherRowDimensionList(@Param("viewId") String viewId, @Param("groupRow") Integer groupRow);
    /**
     * 获取列维度
     *
     * @param viewId
     * @return
     */
    @Query(" FROM ViewDimension WHERE viewId = :viewId AND dimensionType = 'col' ORDER BY columnDrillOrder ASC ")
    List<ViewDimension> getColDimensionList(@Param("viewId") String viewId);
}

+ 3 - 1
src/main/java/com/yihu/quota/dao/view/ViewQuotaDao.java

@ -8,10 +8,12 @@ import java.util.List;
/**
 * 视图指标 DAO
 *
 * @author janseny
 * @date 2018年9月26日
 */
public interface ViewQuotaDao extends PagingAndSortingRepository<ViewQuota, Integer> {
public interface ViewQuotaDao extends PagingAndSortingRepository<ViewQuota, String> {
    List<ViewQuota> findByViewId(@Param("viewId") String viewId);

+ 3 - 1
src/main/java/com/yihu/quota/dao/view/ViewQuotaFilterDao.java

@ -8,10 +8,12 @@ import java.util.List;
/**
 * 视图、指标的过滤条件 DAO
 *
 * @author janseny
 * @date 2018年9月26日
 */
public interface ViewQuotaFilterDao extends PagingAndSortingRepository<ViewQuotaFilter, Integer> {
public interface ViewQuotaFilterDao extends PagingAndSortingRepository<ViewQuotaFilter, String> {
    List<ViewQuotaFilter> findByRelationId(@Param("relationId") String relationId);

+ 33 - 6
src/main/java/com/yihu/quota/model/view/View.java

@ -9,6 +9,7 @@ import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.List;
import java.util.Map;
/**
 * 视图 entity
@ -35,9 +36,17 @@ public class View extends BaseAssignedEntity {
     */
    private List<ViewQuotaFilter> viewFilterList;
    /**
     * 视图维度
     * 视图各组组内顶层行维度
     */
    private List<ViewDimension> viewDimensionList;
    private List<ViewDimension> groupTopRowDimensionList;
    /**
     * 视图各组组内其他行维度
     */
    private Map<Integer, List<ViewDimension>> groupOtherRowDimensionsMap;
    /**
     * 视图列维度
     */
    private List<ViewDimension> colDimensionList;
    /**
     * 视图指标
     */
@ -125,15 +134,33 @@ public class View extends BaseAssignedEntity {
    }
    @Transient
    public List<ViewDimension> getViewDimensionList() {
        return viewDimensionList;
    public List<ViewDimension> getGroupTopRowDimensionList() {
        return groupTopRowDimensionList;
    }
    public void setGroupTopRowDimensionList(List<ViewDimension> groupTopRowDimensionList) {
        this.groupTopRowDimensionList = groupTopRowDimensionList;
    }
    @Transient
    public Map<Integer, List<ViewDimension>> getGroupOtherRowDimensionsMap() {
        return groupOtherRowDimensionsMap;
    }
    public void setGroupOtherRowDimensionsMap(Map<Integer, List<ViewDimension>> groupOtherRowDimensionsMap) {
        this.groupOtherRowDimensionsMap = groupOtherRowDimensionsMap;
    }
    @Transient
    public void setViewDimensionList(List<ViewDimension> viewDimensionList) {
        this.viewDimensionList = viewDimensionList;
    public List<ViewDimension> getColDimensionList() {
        return colDimensionList;
    }
    public void setColDimensionList(List<ViewDimension> colDimensionList) {
        this.colDimensionList = colDimensionList;
    }
    @Transient
    public List<ViewQuota> getViewQuotaList() {
        return viewQuotaList;
    }

+ 24 - 23
src/main/java/com/yihu/quota/model/view/ViewDimension.java

@ -9,6 +9,7 @@ import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 视图维度 entity
 *
 * @author janseny
 * @date 2018年9月26日
@ -17,25 +18,24 @@ import javax.persistence.Table;
@Table(name = "olap_view_dimension")
public class ViewDimension extends BaseAssignedEntity {
    public Integer viewId; // 视图Id
    public String viewId; // 视图Id
    public String dimensionCode; // 维度编码
    public String dimensionName; // 维度名称
    public String esIndex; // 多维数据集的 ES index
    public String esType; //  多维数据集的 ES type
    public String rankType; // 行列维度类型,row:行维度,col:列维度,默认行维度。
    public String dimensionType; // 维度类型,row:行维度,col:列维度,drill:钻取维度,默认行维度。
    public Integer groupRow; // 行维度组
    public Integer groupRowOrder; // 组内行维度顺序
    public Integer rowOrder; //可钻取的行维度顺序
    public Integer columnOrder; //列维度顺序
    public Integer columnDrillOrder; //列维度/钻取维度的顺序
    public String rowMemberOrderType; //行维度成员排序方式,name:按名称排序,sub_agg:按子聚合统计值排序,默认按名称排序。
    public Integer rowMemberCount; //行维度成员返回个数
    @Column(name = "view_id")
    public Integer getViewId() {
    public String getViewId() {
        return viewId;
    }
    public void setViewId(Integer viewId) {
    public void setViewId(String viewId) {
        this.viewId = viewId;
    }
@ -47,6 +47,7 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setDimensionCode(String dimensionCode) {
        this.dimensionCode = dimensionCode;
    }
    @Column(name = "dimension_name")
    public String getDimensionName() {
        return dimensionName;
@ -55,6 +56,7 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setDimensionName(String dimensionName) {
        this.dimensionName = dimensionName;
    }
    @Column(name = "es_index")
    public String getEsIndex() {
        return esIndex;
@ -63,6 +65,7 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setEsIndex(String esIndex) {
        this.esIndex = esIndex;
    }
    @Column(name = "es_type")
    public String getEsType() {
        return esType;
@ -71,14 +74,16 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setEsType(String esType) {
        this.esType = esType;
    }
    @Column(name = "rank_type")
    public String getRankType() {
        return rankType;
    @Column(name = "dimension_type")
    public String getDimensionType() {
        return dimensionType;
    }
    public void setRankType(String rankType) {
        this.rankType = rankType;
    public void setDimensionType(String dimensionType) {
        this.dimensionType = dimensionType;
    }
    @Column(name = "group_row")
    public Integer getGroupRow() {
        return groupRow;
@ -87,6 +92,7 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setGroupRow(Integer groupRow) {
        this.groupRow = groupRow;
    }
    @Column(name = "group_row_order")
    public Integer getGroupRowOrder() {
        return groupRowOrder;
@ -95,22 +101,16 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setGroupRowOrder(Integer groupRowOrder) {
        this.groupRowOrder = groupRowOrder;
    }
    @Column(name = "row_order")
    public Integer getRowOrder() {
        return rowOrder;
    }
    public void setRowOrder(Integer rowOrder) {
        this.rowOrder = rowOrder;
    }
    @Column(name = "column_order")
    public Integer getColumnOrder() {
        return columnOrder;
    @Column(name = "column_drill_order")
    public Integer getColumnDrillOrder() {
        return columnDrillOrder;
    }
    public void setColumnOrder(Integer columnOrder) {
        this.columnOrder = columnOrder;
    public void setColumnDrillOrder(Integer columnDrillOrder) {
        this.columnDrillOrder = columnDrillOrder;
    }
    @Column(name = "row_member_order_type")
    public String getRowMemberOrderType() {
        return rowMemberOrderType;
@ -119,6 +119,7 @@ public class ViewDimension extends BaseAssignedEntity {
    public void setRowMemberOrderType(String rowMemberOrderType) {
        this.rowMemberOrderType = rowMemberOrderType;
    }
    @Column(name = "row_member_count")
    public Integer getRowMemberCount() {
        return rowMemberCount;

+ 3 - 3
src/main/java/com/yihu/quota/model/view/ViewQuota.java

@ -20,7 +20,7 @@ import java.util.List;
@Table(name = "olap_view_quota")
public class ViewQuota extends BaseAssignedEntity {
    public Integer viewId; // 视图Id
    public String viewId; // 视图Id
    public String dimensionCode; // 维度编码
    public String dimensionName; // 维度名称
    public String esIndex; // 多维数据集的 ES index
@ -36,11 +36,11 @@ public class ViewQuota extends BaseAssignedEntity {
    public List<ViewQuotaFilter> quotaFilterList;
    @Column(name = "view_id")
    public Integer getViewId() {
    public String getViewId() {
        return viewId;
    }
    public void setViewId(Integer viewId) {
    public void setViewId(String viewId) {
        this.viewId = viewId;
    }

+ 9 - 1
src/main/java/com/yihu/quota/model/view/ViewQuotaFilter.java

@ -9,6 +9,7 @@ import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 视图、指标过滤条件 entity
 *
 * @author janseny
 * @date 2018年9月26日
@ -24,7 +25,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public String esType; //  多维数据集的 ES type
    public String filterType; // 过滤条件类型,view:视图,quota:指标。
    public String relationType; // 关系类型,关系类型,and:且,or:或
    public String compareType; //比较类型,belong:属于,not_belong:不属于,null:为空,not_null:非空,start_with:开头是,end_with:结尾是,contain:包含,not_contain:不包含
    public String compareType; //比较类型,belong:属于,not_belong:不属于,null:为空,not_null:非空,gt:大于,gte:大于等于,小于:lt,小于等于:lte,contain:包含,not_contain:不包含
    public String filterValue; //过滤的值
    @Column(name = "relation_id")
@ -44,6 +45,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setDimensionCode(String dimensionCode) {
        this.dimensionCode = dimensionCode;
    }
    @Column(name = "dimension_name")
    public String getDimensionName() {
        return dimensionName;
@ -52,6 +54,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setDimensionName(String dimensionName) {
        this.dimensionName = dimensionName;
    }
    @Column(name = "es_index")
    public String getEsIndex() {
        return esIndex;
@ -60,6 +63,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setEsIndex(String esIndex) {
        this.esIndex = esIndex;
    }
    @Column(name = "es_type")
    public String getEsType() {
        return esType;
@ -68,6 +72,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setEsType(String esType) {
        this.esType = esType;
    }
    @Column(name = "filter_type")
    public String getFilterType() {
        return filterType;
@ -76,6 +81,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setFilterType(String filterType) {
        this.filterType = filterType;
    }
    @Column(name = "relation_type")
    public String getRelationType() {
        return relationType;
@ -84,6 +90,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setRelationType(String relationType) {
        this.relationType = relationType;
    }
    @Column(name = "compare_type")
    public String getCompareType() {
        return compareType;
@ -92,6 +99,7 @@ public class ViewQuotaFilter extends BaseAssignedEntity {
    public void setCompareType(String compareType) {
        this.compareType = compareType;
    }
    @Column(name = "filter_value")
    public String getFilterValue() {
        return filterValue;

+ 110 - 17
src/main/java/com/yihu/quota/service/view/ViewService.java

@ -17,14 +17,20 @@ import com.yihu.quota.vo.ViewQuotaFilterModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
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.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -51,7 +57,7 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
    @Autowired
    private ObjectMapper objectMapper;
    public View findOne(Integer id) {
    public View findOne(String id) {
        return viewDao.findOne(id);
    }
@ -63,8 +69,21 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
     */
    public View getViewRule(String viewCode) {
        View view = viewDao.findByCode(viewCode);
        // 视图默认过滤条件
        view.setViewFilterList(viewQuotaFilterDao.findByRelationId(view.getId()));
        view.setViewDimensionList(viewDimensionDao.findByViewId(view.getId()));
        // 视图各组组内顶层行维度
        List<ViewDimension> groupTopRowDimensionList = viewDimensionDao.getGroupTopRowDimensionList(view.getId());
        view.setGroupTopRowDimensionList(groupTopRowDimensionList);
        // 视图各组组内其他行维度
        Map<Integer, List<ViewDimension>> groupOtherRowDimensionsMap = new HashMap<>(16);
        for (ViewDimension viewDimension : groupTopRowDimensionList) {
            List<ViewDimension> otherRowDimensionList = viewDimensionDao.getGroupOtherRowDimensionList(view.getId(), viewDimension.getGroupRow());
            groupOtherRowDimensionsMap.put(viewDimension.getGroupRow(), otherRowDimensionList);
        }
        view.setGroupOtherRowDimensionsMap(groupOtherRowDimensionsMap);
        // 视图列维度
        view.setColDimensionList(viewDimensionDao.getColDimensionList(view.getId()));
        // 视图指标
        view.setViewQuotaList(viewQuotaDao.findByViewId(view.getId()));
        for (ViewQuota viewQuota : view.getViewQuotaList()) {
            List<ViewQuotaFilter> quotaFilterList = viewQuotaFilterDao.findByRelationId(viewQuota.getId());
@ -77,33 +96,107 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
     * 获取视图统计结果
     *
     * @param viewCode
     * @param filters
     * @param filterModelList
     */
    public void statViewResult(String viewCode, String filters) throws IOException {
    public Aggregations statViewResult(String viewCode, List<ViewQuotaFilterModel> filterModelList) throws IOException {
        // 获取视图规则
        View view = viewDao.findByCode(viewCode);
        String[] esIndices = view.getEsIndex().split(",");
        String[] esTypes = view.getEsType().split(",");
        // 根据视图规则组装 ES 聚合语句
        TransportClient transportClient = elasticSearchPool.getClient();
        SearchRequestBuilder searchRequest = transportClient.prepareSearch(esIndices).setTypes(esTypes).setSize(0);
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotEmpty(filters)) {
            List<ViewQuotaFilterModel> filterModelList = objectMapper.readValue(filters, new TypeReference<List<ViewQuotaFilterModel>>() {
            });
            for (ViewQuotaFilterModel filterModel : filterModelList) {
                if ("and".equals(filterModel.getRelationType())) {
                    if ("".equals(filterModel.getCompareType())) {
//                        queryBuilder.must(QueryBuilders);
                    }
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(esIndices).setTypes(esTypes).setSize(0);
        // 组装页面传入的过滤条件
        BoolQueryBuilder viewBoolQueryBuilder = QueryBuilders.boolQuery();
        joinViewFilters(viewBoolQueryBuilder, filterModelList);
        // 组装视图默认过滤条件
        String viewFilterStr = objectMapper.writeValueAsString(view.getViewFilterList());
        List<ViewQuotaFilterModel> viewFilterModelList = objectMapper.readValue(viewFilterStr, new TypeReference<List<ViewQuotaFilterModel>>() {
        });
        joinViewFilters(viewBoolQueryBuilder, viewFilterModelList);
        searchRequestBuilder.setQuery(viewBoolQueryBuilder);
        // 组装聚合
        List<ViewDimension> groupTopRowDimensionList = view.getGroupTopRowDimensionList();
        if (groupTopRowDimensionList.size() != 0) {
            int indexCount = esIndices.length;
            for (ViewDimension viewDimension : groupTopRowDimensionList) {
                // 有多个多维度数据集时,设定顶层聚合的数据来自哪个多维数据集
                if (indexCount > 1) {
                    AggregationBuilders.filter(viewDimension.getDimensionCode());
                }
            }
        }
        SearchResponse searchResponse = searchRequestBuilder.get();
        Aggregations aggregations = searchResponse.getAggregations();
        transportClient.close();
        return aggregations;
    }
    /**
     * 拼接视图的过滤条件
     *
     * @param boolQueryBuilder
     * @param viewFilterModelList
     */
    private void joinViewFilters(BoolQueryBuilder boolQueryBuilder, List<ViewQuotaFilterModel> viewFilterModelList) {
        if (viewFilterModelList.size() != 0) {
            for (ViewQuotaFilterModel filterModel : viewFilterModelList) {
                String field = filterModel.getDimensionCode();
                String value = filterModel.getFilterValue();
                // 属于与否,TODO 需要判断字段类型,转换 value 的类型。
                if ("belong".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.termQuery(field, value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                } else if ("not_belong".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.termQuery(field, value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, "not");
                }
                // 为空与否
                else if ("null".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.missingQuery(field).nullValue(true);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                } else if ("not_null".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.missingQuery(field).nullValue(true);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, "not");
                }
                // 包含与否
                else if ("null".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.matchQuery(field, value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                } else if ("not_null".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.matchQuery(field, value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, "not");
                }
                // 范围,TODO 需要判断字段类型,转换 value 的类型。
                else if ("gt".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.rangeQuery(field).gt(value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                } else if ("gte".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.rangeQuery(field).gte(value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                } else if ("lt".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.rangeQuery(field).lt(value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                } else if ("lte".equals(filterModel.getCompareType())) {
                    QueryBuilder queryBuilder = QueryBuilders.rangeQuery(field).lte(value);
                    joinBoolQuery(boolQueryBuilder, queryBuilder, filterModel.getRelationType());
                }
            }
        }
    }
    private void joinBoolQuery(BoolQueryBuilder boolQueryBuilder, QueryBuilder queryBuilder, String relationType) {
        if ("and".equals(relationType)) {
            boolQueryBuilder.must(queryBuilder);
        } else if ("or".equals(relationType)) {
            boolQueryBuilder.should(queryBuilder);
        } else if ("not".equals(relationType)) {
            boolQueryBuilder.mustNot(queryBuilder);
        }
    }
}

+ 0 - 122
src/main/java/com/yihu/quota/util/AggregationBuildHandler.java

@ -1,122 +0,0 @@
package com.yihu.quota.util;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
 * Created by janseny on 2018/9/28.
 */
@Component
public class AggregationBuildHandler {
    /**
     * 简单聚合
     * @param aggType 聚合类型
     * @param aggName 聚合名称
     * @param fieldName 聚合字段
     * @return
     */
    public AbstractAggregationBuilder addAggregationBuilder(String aggType,String aggName, String fieldName){
        AbstractAggregationBuilder builder = null;
        if(aggType.equals("sum")){
            builder = AggregationBuilders.sum(aggName).field(fieldName);
        }else if(aggType.equals("count")){
            builder = AggregationBuilders.count(aggName).field(fieldName);
        }else if(aggType.equals("avg")){
            builder = AggregationBuilders.avg(aggName).field(fieldName);
        }else if(aggType.equals("max")){
            builder = AggregationBuilders.max(aggName).field(fieldName);
        }else if(aggType.equals("min")){
            builder = AggregationBuilders.min(aggName).field(fieldName);
        }
        return  builder;
    }
    /**
     * 分组后,简单聚合
     * @param aggType 聚合类型
     * @param aggName 聚合名称
     * @param fieldName 聚合字段
     * @return
     */
    public AbstractAggregationBuilder addTermAggregationBuilder(String termName, String termFieldName,String aggType,String aggName, String fieldName){
        AbstractAggregationBuilder builder = null;
        TermsBuilder termsBuilder = addTermsBuilder(termName,termFieldName);
        if(aggType.equals("sum")){
            builder = termsBuilder.subAggregation(AggregationBuilders.sum(aggName).field(fieldName));
        }else if(aggType.equals("count")){
            builder = termsBuilder.subAggregation(AggregationBuilders.count(aggName).field(fieldName));
        }else if(aggType.equals("avg")){
            builder = termsBuilder.subAggregation(AggregationBuilders.avg(aggName).field(fieldName));
        }else if(aggType.equals("max")){
            builder = termsBuilder.subAggregation(AggregationBuilders.max(aggName).field(fieldName));
        }else if(aggType.equals("min")){
            builder = termsBuilder.subAggregation(AggregationBuilders.min(aggName).field(fieldName));
        }
        return  builder;
    }
    /**
     * 添加分组
     * @param termName
     * @param fieldName
     * @return
     */
    public TermsBuilder addTermsBuilder(String termName, String fieldName){
        TermsBuilder termsBuilder= AggregationBuilders.terms(termName).field(fieldName);
        return termsBuilder;
    }
    /**
     *
     * @param client
     * @param boolQueryBuilder  查询的过滤条件
     * @param aggBuilderList  聚合组
     *  聚合组中成员是 单个的聚合查询,其中单个的聚合查询可以嵌套子聚合查询 如:
     *  单个聚合 查询 :TermsBuilder firstAgg= AggregationBuilders.terms("player_count ").field("team");
     *  带有子聚合的聚合查询 :
     *    TermsBuilder secondAgg= AggregationBuilders.terms("pos_count").field("position")
     *      .subAggregation(
     *          AggregationBuilders.dateHistogram("by_year").field("dateOfBirth").interval((DateHistogramInterval.YEAR))
     *              .subAggregation(
     *                  AggregationBuilders.avg("avg_children").field("children")
     *              )
     *          );
     * @return 结果集
     */
    public List<Map<String, Object>> structAggregationQuery(TransportClient client,String index,String type,
                                                            BoolQueryBuilder boolQueryBuilder,
                                                            LinkedList<AbstractAggregationBuilder> aggBuilderList){
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type).
                setQuery(boolQueryBuilder);
        for(AbstractAggregationBuilder aggBuilder : aggBuilderList){
            searchRequestBuilder.addAggregation(aggBuilder);
        }
        SearchResponse sr = searchRequestBuilder.execute().actionGet();
        List<Map<String, Object>> matchRsult = new LinkedList<Map<String, Object>>();
        //数据解析 TODO
//        ValueCount sum = sr.getAggregations().get("count_result");
//        double v = sum.getValue();
        client.close();
        return matchRsult;
    }
}

+ 12 - 12
src/main/java/com/yihu/quota/vo/ViewQuotaFilterModel.java

@ -9,28 +9,28 @@ package com.yihu.quota.vo;
public class ViewQuotaFilterModel {
    /**
     * 字段编码
     * 维度字段
     */
    private String field;
    private String dimensionCode;
    /**
     * 关系类型,and:且,or:或
     */
    private String relationType;
    /**
     * 比较类型,belong:属于,not_belong:不属于,null:为空,not_null:非空,start_with:开头是,end_with:结尾是,contain:包含,not_contain:不包含
     * 比较类型,belong:属于,not_belong:不属于,null:为空,not_null:非空,gt:大于,gte:大于等于,小于:lt,小于等于:lte,contain:包含,not_contain:不包含
     */
    private String compareType;
    /**
     * 过滤的值
     */
    private String value;
    private String filterValue;
    public String getField() {
        return field;
    public String getDimensionCode() {
        return dimensionCode;
    }
    public void setField(String field) {
        this.field = field;
    public void setDimensionCode(String dimensionCode) {
        this.dimensionCode = dimensionCode;
    }
    public String getRelationType() {
@ -49,11 +49,11 @@ public class ViewQuotaFilterModel {
        this.compareType = compareType;
    }
    public String getValue() {
        return value;
    public String getFilterValue() {
        return filterValue;
    }
    public void setValue(String value) {
        this.value = value;
    public void setFilterValue(String filterValue) {
        this.filterValue = filterValue;
    }
}