Procházet zdrojové kódy

根据参数动态调整视图规则。

zhangjinjun před 6 roky
rodič
revize
24ae0949f1

+ 16 - 10
src/main/java/com/yihu/quota/controller/ViewController.java

@ -107,27 +107,33 @@ public class ViewController extends EnvelopRestEndPoint {
    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\":\"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 = "drillDimension", value = "钻取维度编码,如:'{\"field\":\"event_date\"}'")
            @RequestParam(value = "drillDimension", required = false) String drillDimension) throws Exception {
            @ApiParam(name = "filterJsonStr", value = "过滤条件JSON字符串,上卷/下钻时需动态移除/添加钻取维度值作为过滤条件," +
                    "如:'[{\"relationType\":\"and\",\"field\":\"event_date\",\"compareType\":\"belong\",\"filterValue\":\"2017-06-11\"}]',relationType 可取值'and|or'。")
            @RequestParam(value = "filterJsonStr", required = false) String filterJsonStr,
            @ApiParam(name = "sortJsonStr", value = "排序JSON字符串,排序字段从可排序的维度中挑选,如:'{\"cubeCode\":\"xxx\",\"field\":\"event_date\",\"sort\":\"asc\"}',cubeCode 为多维数据集编码。")
            @RequestParam(value = "sortJsonStr", required = false) String sortJsonStr,
            @ApiParam(name = "drillJsonStr", value = "钻取维度JSON字符串,如:'{\"cubeCode\":\"xxx\",\"field\":\"event_date\",\"replaced\":{\"cubeCode\":\"xxx\",\"field\":\"event_date\"}}'," +
                    "cubeCode 为多维数据集编码,replaced 为被替换的行维度。")
            @RequestParam(value = "drillJsonStr", required = false) String drillJsonStr) throws Exception {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(true);
        try {
            View view = viewService.findByCode(viewCode);
            // 获取视图的完整规则
            View view = viewService.getViewRule(viewCode);
            if (view == null) {
                throw new ApiException("视图不存在。");
            }
            // 根据参数动态调整视图规则
            viewService.adjustViewRule(view, sortJsonStr, drillJsonStr);
            // 根据视图规则,获取统计结果
            List<ViewQuotaFilterModel> filterModelList = new ArrayList<>();
            if (StringUtils.isNotEmpty(filters)) {
                filterModelList = objectMapper.readValue(filters, new TypeReference<List<ViewQuotaFilterModel>>() {
            if (StringUtils.isNotEmpty(filterJsonStr)) {
                filterModelList = objectMapper.readValue(filterJsonStr, new TypeReference<List<ViewQuotaFilterModel>>() {
                });
            }
            Aggregations aggregations = viewService.statViewResult(viewCode, filterModelList);
            Aggregations aggregations = viewService.statViewResult(view, filterModelList);
            // 转换统计结果数据格式
            if (view.getDisplayType().equals("1")) {

+ 85 - 32
src/main/java/com/yihu/quota/service/view/ViewService.java

@ -86,7 +86,7 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
        return viewDao.findOne(id);
    }
    public View findByCode(String viewCode){
    public View findByCode(String viewCode) {
        return viewDao.findByCode(viewCode);
    }
@ -99,42 +99,95 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
     */
    public View getViewRule(String viewCode) {
        View view = viewDao.findByCode(viewCode);
        // 视图默认过滤条件
        view.setViewFilterList(viewQuotaFilterDao.findByRelationId(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());
            viewQuota.setQuotaFilterList(quotaFilterList);
        if (view != null) {
            // 视图默认过滤条件
            view.setViewFilterList(viewQuotaFilterDao.findByRelationId(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());
                viewQuota.setQuotaFilterList(quotaFilterList);
            }
        }
        return view;
    }
    /**
     * 根据动态条件,调整视图规则
     *
     * @param viewRule     原视图规则
     * @param sortJsonStr  排序JSON字符串,如:'{"cubeCode":"xxx","field":"event_date","sort":"asc"}',cubeCode 为多维数据集编码。
     * @param drillJsonStr 钻取维度JSON字符串,如:'{"cubeCode":"xxx","field":"event_date","replaced":{"cubeCode":"xxx","field":"event_date"}}',
     *                     "cubeCode 为多维数据集编码,replaced 为被替换的行维度。
     * @return
     */
    public void adjustViewRule(View viewRule, String sortJsonStr, String drillJsonStr) throws Exception {
        List<ViewDimension> topDimensionList = viewRule.getGroupTopRowDimensionList();
        Map<Integer, List<ViewDimension>> groupOtherDimensionMap = viewRule.getGroupOtherRowDimensionsMap();
        // 目前动态排序,只能针对一个行维度、没有列维度、一个指标场合。
        if (StringUtils.isNotEmpty(sortJsonStr)) {
            Map<String, String> sortMap = objectMapper.readValue(sortJsonStr, Map.class);
            String cubeCode = sortMap.get("cubeCode") != null ? sortMap.get("cubeCode").toString() : "";
            String field = sortMap.get("field") != null ? sortMap.get("field").toString() : "";
            String sort = sortMap.get("sort") != null ? sortMap.get("sort").toString() : "";
            for (ViewDimension dimension : topDimensionList) {
                if (cubeCode.equals(dimension.getCubeCode()) && field.equals(dimension.getDimensionCode())) {
                    dimension.setMemberOrderStrategy(sort);
                }
            }
        }
        // 钻取只能针对行维度
        if (StringUtils.isNotEmpty(drillJsonStr)) {
            Map<String, Object> drillMap = objectMapper.readValue(drillJsonStr, Map.class);
            String cubeCode = drillMap.get("cubeCode") != null ? drillMap.get("cubeCode").toString() : "";
            String field = drillMap.get("field") != null ? drillMap.get("field").toString() : "";
            Map<String, String> replaced = (Map) drillMap.get("replaced");
            if (replaced == null) {
                throw new ApiException("钻取维度JSON字符串缺少被替换的维度。");
            }
            String replacedCubeCode = replaced.get("cubeCode") != null ? drillMap.get("cubeCode").toString() : "";
            String replacedField = replaced.get("field") != null ? drillMap.get("field").toString() : "";
            for (ViewDimension dimension : topDimensionList) {
                if (replacedCubeCode.equals(dimension.getCubeCode()) && replacedField.equals(dimension.getDimensionCode())) {
                    dimension.setCubeCode(cubeCode);
                    dimension.setDimensionCode(field);
                }
                List<ViewDimension> otherDimensionList = groupOtherDimensionMap.get(dimension.getGroupRow());
                for (ViewDimension otherDimension : otherDimensionList) {
                    if (replacedCubeCode.equals(otherDimension.getCubeCode()) && replacedField.equals(otherDimension.getDimensionCode())) {
                        otherDimension.setCubeCode(cubeCode);
                        otherDimension.setDimensionCode(field);
                    }
                }
            }
        }
    }
    /**
     * 获取视图统计结果
     *
     * @param viewCode        视图编码
     * @param viewRule        视图,包含完整规则
     * @param filterModelList 页面的过滤条件模型集合
     * @return ES聚合对象
     * @author 张进军
     */
    public Aggregations statViewResult(String viewCode, List<ViewQuotaFilterModel> filterModelList) throws Exception {
        // 获取视图规则
        View view = this.getViewRule(viewCode);
        String[] esIndices = view.getEsIndex().split(",");
        String[] esTypes = view.getEsType().split(",");
    public Aggregations statViewResult(View viewRule, List<ViewQuotaFilterModel> filterModelList) throws Exception {
        String[] esIndices = viewRule.getEsIndex().split(",");
        String[] esTypes = viewRule.getEsType().split(",");
        int indexCount = esIndices.length;
        TransportClient transportClient = elasticSearchPool.getClient();
@ -144,24 +197,24 @@ public class ViewService extends BaseJpaService<View, ViewDao> {
        BoolQueryBuilder viewBoolQueryBuilder = QueryBuilders.boolQuery();
        this.joinFilters(viewBoolQueryBuilder, filterModelList);
        // 组装视图默认过滤条件
        String viewFilterStr = objectMapper.writeValueAsString(view.getViewFilterList());
        String viewFilterStr = objectMapper.writeValueAsString(viewRule.getViewFilterList());
        List<ViewQuotaFilterModel> viewFilterModelList = objectMapper.readValue(viewFilterStr, new TypeReference<List<ViewQuotaFilterModel>>() {
        });
        this.joinFilters(viewBoolQueryBuilder, viewFilterModelList);
        searchRequestBuilder.setQuery(viewBoolQueryBuilder);
        // 视图的顶层行维度
        List<ViewDimension> groupTopRowDimensionList = view.getGroupTopRowDimensionList();
        List<ViewDimension> groupTopRowDimensionList = viewRule.getGroupTopRowDimensionList();
        // 视图的组内其他行维度
        Map<Integer, List<ViewDimension>> groupOtherRowDimensionsMap = view.getGroupOtherRowDimensionsMap();
        Map<Integer, List<ViewDimension>> groupOtherRowDimensionsMap = viewRule.getGroupOtherRowDimensionsMap();
        // 视图的列维度
        List<ViewDimension> colDimensionList = view.getColDimensionList();
        List<ViewDimension> colDimensionList = viewRule.getColDimensionList();
        // 视图的指标
        List<ViewQuota> viewQuotaList = view.getViewQuotaList();
        List<ViewQuota> viewQuotaList = viewRule.getViewQuotaList();
        //region 聚合组装
        if (groupTopRowDimensionList.size() == 0) {
            if (!"1".equals(view.getDisplayType())) {
            if (!"1".equals(viewRule.getDisplayType())) {
                // 视图展示为非数值类型场合
                throw new ApiException("请为视图至少配置一个行维度。");
            } else if (viewQuotaList == null || viewQuotaList.size() == 0) {