From f2e82072451c61f63635ac95c24cafda3d188d0b Mon Sep 17 00:00:00 2001 From: LXW <1264174498@qq.com> Date: Mon, 16 Oct 2023 16:43:09 +0800 Subject: [PATCH] (improvement)(semantic) support metric relate dimension setting (#229) Co-authored-by: jolunoluo --- .../api/component/SemanticInterpreter.java | 4 +- .../chat/api/pojo/RelateSchemaElement.java | 13 ++++ .../chat/api/pojo/SchemaElement.java | 3 +- .../chat/api/pojo/request/QueryDataReq.java | 4 +- .../chat/api/pojo/request/RecommendReq.java | 13 ++++ .../rule/metric/MetricSemanticQuery.java | 54 +++++++++++++- .../chat/rest/RecommendController.java | 36 ++++------ .../chat/service/RecommendService.java | 8 +-- .../service/impl/RecommendServiceImpl.java | 42 ++++++++--- .../semantic/BaseSemanticInterpreter.java | 8 +-- .../semantic/ModelSchemaBuilder.java | 30 ++++++-- .../main/resources/db/semantic-schema-h2.sql | 2 + .../tencent/supersonic/LoadModelDataDemo.java | 3 +- .../src/main/resources/db/schema-h2.sql | 2 + .../src/main/resources/db/schema-mysql.sql | 2 + .../src/main/resources/db/sql-update.sql | 6 +- .../src/test/resources/db/schema-h2.sql | 2 + .../api/model/pojo/DrillDownDimension.java | 16 +++++ .../semantic/api/model/pojo/Measure.java | 5 ++ .../api/model/pojo/RelateDimension.java | 17 +++++ .../api/model/request/MetricBaseReq.java | 4 +- .../semantic/api/model/request/ModelReq.java | 3 + .../api/model/response/MetricResp.java | 3 + .../api/model/response/ModelResp.java | 3 + .../model/application/MetricServiceImpl.java | 24 +++++++ .../model/application/ModelServiceImpl.java | 18 +++-- .../semantic/model/domain/MetricService.java | 3 + .../model/domain/dataobject/MetricDO.java | 21 ++++++ .../domain/dataobject/MetricDOExample.java | 70 +++++++++++++++++++ .../model/domain/dataobject/ModelDO.java | 21 ++++++ .../domain/dataobject/ModelDOExample.java | 70 +++++++++++++++++++ .../semantic/model/domain/pojo/Metric.java | 3 + .../semantic/model/domain/pojo/Model.java | 13 +--- .../model/domain/utils/MetricConverter.java | 7 ++ .../model/domain/utils/ModelConvert.java | 3 + .../semantic/model/rest/MetricController.java | 6 ++ .../main/resources/mapper/MetricDOMapper.xml | 22 ++++-- .../main/resources/mapper/ModelDOMapper.xml | 31 ++++++-- 38 files changed, 508 insertions(+), 87 deletions(-) create mode 100644 chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/RelateSchemaElement.java create mode 100644 chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/RecommendReq.java create mode 100644 semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/DrillDownDimension.java create mode 100644 semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/RelateDimension.java diff --git a/chat/api/src/main/java/com/tencent/supersonic/chat/api/component/SemanticInterpreter.java b/chat/api/src/main/java/com/tencent/supersonic/chat/api/component/SemanticInterpreter.java index 7e7caaf13..c99820095 100644 --- a/chat/api/src/main/java/com/tencent/supersonic/chat/api/component/SemanticInterpreter.java +++ b/chat/api/src/main/java/com/tencent/supersonic/chat/api/component/SemanticInterpreter.java @@ -47,9 +47,9 @@ public interface SemanticInterpreter { ModelSchema getModelSchema(Long model, Boolean cacheEnable); - PageInfo getDimensionPage(PageDimensionReq pageDimensionCmd); + PageInfo getDimensionPage(PageDimensionReq pageDimensionReq); - PageInfo getMetricPage(PageMetricReq pageMetricCmd, User user); + PageInfo getMetricPage(PageMetricReq pageDimensionReq, User user); List getDomainList(User user); diff --git a/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/RelateSchemaElement.java b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/RelateSchemaElement.java new file mode 100644 index 000000000..99a497555 --- /dev/null +++ b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/RelateSchemaElement.java @@ -0,0 +1,13 @@ +package com.tencent.supersonic.chat.api.pojo; + + +import lombok.Data; + +@Data +public class RelateSchemaElement { + + private Long dimensionId; + + private boolean isNecessary; + +} diff --git a/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/SchemaElement.java b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/SchemaElement.java index 94abc0da5..2f6f86cb1 100644 --- a/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/SchemaElement.java +++ b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/SchemaElement.java @@ -22,10 +22,9 @@ public class SchemaElement implements Serializable { private String bizName; private Long useCnt; private SchemaElementType type; - private List alias; - private List schemaValueMaps; + private List relateSchemaElements; private String defaultAgg; diff --git a/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/QueryDataReq.java b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/QueryDataReq.java index ed1395a83..b11ce0ce0 100644 --- a/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/QueryDataReq.java +++ b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/QueryDataReq.java @@ -16,6 +16,6 @@ public class QueryDataReq { private Set dimensionFilters = new HashSet<>(); private Set metricFilters = new HashSet<>(); private DateConf dateInfo; - private Long queryId = 7L; - private Integer parseId = 2; + private Long queryId; + private Integer parseId; } diff --git a/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/RecommendReq.java b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/RecommendReq.java new file mode 100644 index 000000000..cf2b3585a --- /dev/null +++ b/chat/api/src/main/java/com/tencent/supersonic/chat/api/pojo/request/RecommendReq.java @@ -0,0 +1,13 @@ +package com.tencent.supersonic.chat.api.pojo.request; + + +import lombok.Data; + +@Data +public class RecommendReq { + + private Long modelId; + + private Long metricId; + +} \ No newline at end of file diff --git a/chat/core/src/main/java/com/tencent/supersonic/chat/query/rule/metric/MetricSemanticQuery.java b/chat/core/src/main/java/com/tencent/supersonic/chat/query/rule/metric/MetricSemanticQuery.java index 85f95b740..45af482ba 100644 --- a/chat/core/src/main/java/com/tencent/supersonic/chat/query/rule/metric/MetricSemanticQuery.java +++ b/chat/core/src/main/java/com/tencent/supersonic/chat/query/rule/metric/MetricSemanticQuery.java @@ -4,9 +4,13 @@ import static com.tencent.supersonic.chat.api.pojo.SchemaElementType.METRIC; import static com.tencent.supersonic.chat.query.rule.QueryMatchOption.OptionType.REQUIRED; import static com.tencent.supersonic.chat.query.rule.QueryMatchOption.RequireNumberType.AT_LEAST; +import com.google.common.collect.Lists; import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.chat.api.pojo.ChatContext; +import com.tencent.supersonic.chat.api.pojo.ModelSchema; import com.tencent.supersonic.chat.api.pojo.QueryContext; +import com.tencent.supersonic.chat.api.pojo.RelateSchemaElement; +import com.tencent.supersonic.chat.api.pojo.SchemaElement; import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch; import com.tencent.supersonic.chat.api.pojo.SchemaElementType; import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq; @@ -24,7 +28,11 @@ import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaR import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -66,7 +74,6 @@ public abstract class MetricSemanticQuery extends RuleSemanticQuery { for (SchemaElementMatch schemaElementMatch : candidateElementMatches) { SchemaElementType type = schemaElementMatch.getElement().getType(); - if (SchemaElementType.DIMENSION.equals(type) || SchemaElementType.VALUE.equals(type)) { if (!blackDimIdList.contains(schemaElementMatch.getElement().getId())) { filteredMatches.add(schemaElementMatch); @@ -79,9 +86,54 @@ public abstract class MetricSemanticQuery extends RuleSemanticQuery { filteredMatches.add(schemaElementMatch); } } + filteredMatches = metricRelateDimensionCheck(filteredMatches, modelId); return filteredMatches; } + private List metricRelateDimensionCheck(List elementMatches, Long modelId) { + List filterSchemaElementMatch = Lists.newArrayList(); + + ModelSchema modelSchema = semanticInterpreter.getModelSchema(modelId, true); + Set metricElements = modelSchema.getMetrics(); + Map valueElementMatchMap = elementMatches.stream() + .filter(elementMatch -> + SchemaElementType.VALUE.equals(elementMatch.getElement().getType()) + || SchemaElementType.ID.equals(elementMatch.getElement().getType())) + .collect(Collectors.toMap(elementMatch -> elementMatch.getElement().getId(), e -> e, (e1, e2) -> e1)); + Map metricMap = metricElements.stream() + .collect(Collectors.toMap(SchemaElement::getId, e -> e, (e1, e2) -> e2)); + + for (SchemaElementMatch schemaElementMatch : elementMatches) { + if (!SchemaElementType.METRIC.equals(schemaElementMatch.getElement().getType())) { + filterSchemaElementMatch.add(schemaElementMatch); + continue; + } + SchemaElement metric = metricMap.get(schemaElementMatch.getElement().getId()); + if (metric == null) { + continue; + } + List relateSchemaElements = metric.getRelateSchemaElements(); + if (CollectionUtils.isEmpty(relateSchemaElements)) { + filterSchemaElementMatch.add(schemaElementMatch); + continue; + } + List necessaryDimensionIds = relateSchemaElements.stream() + .filter(RelateSchemaElement::isNecessary).map(RelateSchemaElement::getDimensionId) + .collect(Collectors.toList()); + boolean flag = true; + for (Long necessaryDimensionId : necessaryDimensionIds) { + if (!valueElementMatchMap.containsKey(necessaryDimensionId)) { + flag = false; + break; + } + } + if (flag) { + filterSchemaElementMatch.add(schemaElementMatch); + } + } + return filterSchemaElementMatch; + } + @Override public void fillParseInfo(Long modelId, QueryContext queryContext, ChatContext chatContext) { super.fillParseInfo(modelId, queryContext, chatContext); diff --git a/chat/core/src/main/java/com/tencent/supersonic/chat/rest/RecommendController.java b/chat/core/src/main/java/com/tencent/supersonic/chat/rest/RecommendController.java index 42021f944..68649e5e7 100644 --- a/chat/core/src/main/java/com/tencent/supersonic/chat/rest/RecommendController.java +++ b/chat/core/src/main/java/com/tencent/supersonic/chat/rest/RecommendController.java @@ -1,21 +1,15 @@ package com.tencent.supersonic.chat.rest; -import com.tencent.supersonic.auth.api.authentication.utils.UserHolder; -import com.tencent.supersonic.chat.api.pojo.request.QueryReq; +import com.tencent.supersonic.chat.api.pojo.request.RecommendReq; import com.tencent.supersonic.chat.api.pojo.response.RecommendQuestionResp; import com.tencent.supersonic.chat.api.pojo.response.RecommendResp; import com.tencent.supersonic.chat.service.RecommendService; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; - import java.util.List; /** @@ -30,31 +24,25 @@ public class RecommendController { @GetMapping("recommend/{modelId}") public RecommendResp recommend(@PathVariable("modelId") Long modelId, - @RequestParam(value = "limit", required = false) Long limit, - HttpServletRequest request, - HttpServletResponse response) { - QueryReq queryCtx = new QueryReq(); - queryCtx.setUser(UserHolder.findUser(request, response)); - queryCtx.setModelId(modelId); - return recommendService.recommend(queryCtx, limit); + @RequestParam(value = "limit", required = false) Long limit) { + RecommendReq recommendReq = new RecommendReq(); + recommendReq.setModelId(modelId); + return recommendService.recommend(recommendReq, limit); } @GetMapping("recommend/metric/{modelId}") public RecommendResp recommendMetricMode(@PathVariable("modelId") Long modelId, - @RequestParam(value = "limit", required = false) Long limit, - HttpServletRequest request, - HttpServletResponse response) { - QueryReq queryCtx = new QueryReq(); - queryCtx.setUser(UserHolder.findUser(request, response)); - queryCtx.setModelId(modelId); - return recommendService.recommendMetricMode(queryCtx, limit); + @RequestParam(value = "metric", required = false) Long metricId, + @RequestParam(value = "limit", required = false) Long limit) { + RecommendReq recommendReq = new RecommendReq(); + recommendReq.setModelId(modelId); + recommendReq.setMetricId(metricId); + return recommendService.recommendMetricMode(recommendReq, limit); } @GetMapping("recommend/question") public List recommendQuestion( - @RequestParam(value = "modelId", required = false) Long modelId, - HttpServletRequest request, - HttpServletResponse response) { + @RequestParam(value = "modelId", required = false) Long modelId) { return recommendService.recommendQuestion(modelId); } } diff --git a/chat/core/src/main/java/com/tencent/supersonic/chat/service/RecommendService.java b/chat/core/src/main/java/com/tencent/supersonic/chat/service/RecommendService.java index 4afa9a611..eec699542 100644 --- a/chat/core/src/main/java/com/tencent/supersonic/chat/service/RecommendService.java +++ b/chat/core/src/main/java/com/tencent/supersonic/chat/service/RecommendService.java @@ -1,10 +1,8 @@ package com.tencent.supersonic.chat.service; - -import com.tencent.supersonic.chat.api.pojo.request.QueryReq; +import com.tencent.supersonic.chat.api.pojo.request.RecommendReq; import com.tencent.supersonic.chat.api.pojo.response.RecommendQuestionResp; import com.tencent.supersonic.chat.api.pojo.response.RecommendResp; - import java.util.List; /*** @@ -12,9 +10,9 @@ import java.util.List; */ public interface RecommendService { - RecommendResp recommend(QueryReq queryCtx, Long limit); + RecommendResp recommend(RecommendReq recommendReq, Long limit); - RecommendResp recommendMetricMode(QueryReq queryCtx, Long limit); + RecommendResp recommendMetricMode(RecommendReq recommendReq, Long limit); List recommendQuestion(Long modelId); } diff --git a/chat/core/src/main/java/com/tencent/supersonic/chat/service/impl/RecommendServiceImpl.java b/chat/core/src/main/java/com/tencent/supersonic/chat/service/impl/RecommendServiceImpl.java index 704062d91..d20248840 100644 --- a/chat/core/src/main/java/com/tencent/supersonic/chat/service/impl/RecommendServiceImpl.java +++ b/chat/core/src/main/java/com/tencent/supersonic/chat/service/impl/RecommendServiceImpl.java @@ -2,8 +2,9 @@ package com.tencent.supersonic.chat.service.impl; import com.tencent.supersonic.chat.api.pojo.ModelSchema; +import com.tencent.supersonic.chat.api.pojo.RelateSchemaElement; import com.tencent.supersonic.chat.api.pojo.SchemaElement; -import com.tencent.supersonic.chat.api.pojo.request.QueryReq; +import com.tencent.supersonic.chat.api.pojo.request.RecommendReq; import com.tencent.supersonic.chat.api.pojo.response.RecommendQuestionResp; import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter; import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp; @@ -14,12 +15,15 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import com.tencent.supersonic.chat.service.ConfigService; import com.tencent.supersonic.chat.service.RecommendService; import com.tencent.supersonic.chat.service.SemanticService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -37,20 +41,40 @@ public class RecommendServiceImpl implements RecommendService { private SemanticService semanticService; @Override - public RecommendResp recommend(QueryReq queryCtx, Long limit) { + public RecommendResp recommend(RecommendReq recommendReq, Long limit) { if (Objects.isNull(limit) || limit <= 0) { limit = Long.MAX_VALUE; } log.debug("limit:{}", limit); - Long modelId = queryCtx.getModelId(); + Long modelId = recommendReq.getModelId(); if (Objects.isNull(modelId)) { return new RecommendResp(); } - ModelSchema modelSchema = semanticService.getModelSchema(modelId); - + List drillDownDimensions = Lists.newArrayList(); + Set metricElements = modelSchema.getMetrics(); + if (recommendReq.getMetricId() != null && !CollectionUtils.isEmpty(metricElements)) { + Optional metric = metricElements.stream().filter(schemaElement -> + recommendReq.getMetricId().equals(schemaElement.getId()) + && !CollectionUtils.isEmpty(schemaElement.getRelateSchemaElements())) + .findFirst(); + if (metric.isPresent()) { + drillDownDimensions = metric.get().getRelateSchemaElements().stream() + .map(RelateSchemaElement::getDimensionId).collect(Collectors.toList()); + } + } + final List drillDownDimensionsFinal = drillDownDimensions; List dimensions = modelSchema.getDimensions().stream() - .filter(dim -> Objects.nonNull(dim) && Objects.nonNull(dim.getUseCnt())) + .filter(dim -> { + if (Objects.isNull(dim)) { + return false; + } + if (!CollectionUtils.isEmpty(drillDownDimensionsFinal)) { + return drillDownDimensionsFinal.contains(dim.getId()); + } else { + return Objects.nonNull(dim.getUseCnt()); + } + }) .sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed()) .limit(limit) .map(dimSchemaDesc -> { @@ -84,14 +108,14 @@ public class RecommendServiceImpl implements RecommendService { } @Override - public RecommendResp recommendMetricMode(QueryReq queryCtx, Long limit) { - RecommendResp recommendResponse = recommend(queryCtx, limit); + public RecommendResp recommendMetricMode(RecommendReq recommendReq, Long limit) { + RecommendResp recommendResponse = recommend(recommendReq, limit); // filter black Item if (Objects.isNull(recommendResponse)) { return recommendResponse; } - ChatConfigRichResp chatConfigRich = configService.getConfigRichInfo(Long.valueOf(queryCtx.getModelId())); + ChatConfigRichResp chatConfigRich = configService.getConfigRichInfo(recommendReq.getModelId()); if (Objects.nonNull(chatConfigRich) && Objects.nonNull(chatConfigRich.getChatAggRichConfig()) && Objects.nonNull(chatConfigRich.getChatAggRichConfig().getVisibility())) { List blackMetricIdList = chatConfigRich.getChatAggRichConfig().getVisibility().getBlackMetricIdList(); diff --git a/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/BaseSemanticInterpreter.java b/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/BaseSemanticInterpreter.java index 9d62012b5..b1d0b8221 100644 --- a/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/BaseSemanticInterpreter.java +++ b/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/BaseSemanticInterpreter.java @@ -17,7 +17,7 @@ import org.springframework.util.CollectionUtils; public abstract class BaseSemanticInterpreter implements SemanticInterpreter { protected final Cache> modelSchemaCache = - CacheBuilder.newBuilder().expireAfterWrite(60, TimeUnit.SECONDS).build(); + CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build(); @SneakyThrows public List fetchModelSchema(List ids, Boolean cacheEnable) { @@ -33,13 +33,13 @@ public abstract class BaseSemanticInterpreter implements SemanticInterpreter { } @Override - public ModelSchema getModelSchema(Long domain, Boolean cacheEnable) { + public ModelSchema getModelSchema(Long model, Boolean cacheEnable) { List ids = new ArrayList<>(); - ids.add(domain); + ids.add(model); List modelSchemaResps = fetchModelSchema(ids, cacheEnable); if (!CollectionUtils.isEmpty(modelSchemaResps)) { Optional modelSchemaResp = modelSchemaResps.stream() - .filter(d -> d.getId().equals(domain)).findFirst(); + .filter(d -> d.getId().equals(model)).findFirst(); if (modelSchemaResp.isPresent()) { ModelSchemaResp modelSchema = modelSchemaResp.get(); return ModelSchemaBuilder.build(modelSchema); diff --git a/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/ModelSchemaBuilder.java b/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/ModelSchemaBuilder.java index b7ceed424..a79a45825 100644 --- a/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/ModelSchemaBuilder.java +++ b/chat/knowledge/src/main/java/com/tencent/supersonic/knowledge/semantic/ModelSchemaBuilder.java @@ -1,11 +1,14 @@ package com.tencent.supersonic.knowledge.semantic; +import com.google.common.collect.Lists; import com.tencent.supersonic.chat.api.pojo.ModelSchema; +import com.tencent.supersonic.chat.api.pojo.RelateSchemaElement; import com.tencent.supersonic.chat.api.pojo.SchemaElement; import com.tencent.supersonic.chat.api.pojo.SchemaElementType; import com.tencent.supersonic.chat.api.pojo.SchemaValueMap; import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap; import com.tencent.supersonic.semantic.api.model.pojo.Entity; +import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension; import com.tencent.supersonic.semantic.api.model.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp; @@ -29,7 +32,7 @@ public class ModelSchemaBuilder { public static ModelSchema build(ModelSchemaResp resp) { - ModelSchema domainSchema = new ModelSchema(); + ModelSchema modelSchema = new ModelSchema(); SchemaElement domain = SchemaElement.builder() .model(resp.getId()) .id(resp.getId()) @@ -38,7 +41,7 @@ public class ModelSchemaBuilder { .type(SchemaElementType.MODEL) .alias(getAliasList(resp.getAlias())) .build(); - domainSchema.setModel(domain); + modelSchema.setModel(domain); Set metrics = new HashSet<>(); for (MetricSchemaResp metric : resp.getMetrics()) { @@ -53,12 +56,13 @@ public class ModelSchemaBuilder { .type(SchemaElementType.METRIC) .useCnt(metric.getUseCnt()) .alias(alias) + .relateSchemaElements(getRelateSchemaElement(metric)) .defaultAgg(metric.getDefaultAgg()) .build(); metrics.add(metricToAdd); } - domainSchema.getMetrics().addAll(metrics); + modelSchema.getMetrics().addAll(metrics); Set dimensions = new HashSet<>(); Set dimensionValues = new HashSet<>(); @@ -106,8 +110,8 @@ public class ModelSchemaBuilder { .build(); dimensionValues.add(dimValueToAdd); } - domainSchema.getDimensions().addAll(dimensions); - domainSchema.getDimensionValues().addAll(dimensionValues); + modelSchema.getDimensions().addAll(dimensions); + modelSchema.getDimensionValues().addAll(dimensionValues); Entity entity = resp.getEntity(); if (Objects.nonNull(entity)) { @@ -122,11 +126,11 @@ public class ModelSchemaBuilder { entityElement.setType(SchemaElementType.ENTITY); } entityElement.setAlias(entity.getNames()); - domainSchema.setEntity(entityElement); + modelSchema.setEntity(entityElement); } } - return domainSchema; + return modelSchema; } private static List getAliasList(String alias) { @@ -136,4 +140,16 @@ public class ModelSchemaBuilder { return Arrays.asList(alias.split(aliasSplit)); } + private static List getRelateSchemaElement(MetricSchemaResp metricSchemaResp) { + RelateDimension relateDimension = metricSchemaResp.getRelateDimension(); + if (relateDimension == null || CollectionUtils.isEmpty(relateDimension.getDrillDownDimensions())) { + return Lists.newArrayList(); + } + return relateDimension.getDrillDownDimensions().stream().map(dimension -> { + RelateSchemaElement relateSchemaElement = new RelateSchemaElement(); + BeanUtils.copyProperties(dimension, relateSchemaElement); + return relateSchemaElement; + }).collect(Collectors.toList()); + } + } diff --git a/launchers/semantic/src/main/resources/db/semantic-schema-h2.sql b/launchers/semantic/src/main/resources/db/semantic-schema-h2.sql index 2c846cead..375bdd5f8 100644 --- a/launchers/semantic/src/main/resources/db/semantic-schema-h2.sql +++ b/launchers/semantic/src/main/resources/db/semantic-schema-h2.sql @@ -14,6 +14,7 @@ CREATE TABLE IF NOT EXISTS `s2_model` ( `viewer` varchar(3000) DEFAULT NULL , -- domain available users `view_org` varchar(3000) DEFAULT NULL , -- domain available organization `entity` varchar(500) DEFAULT NULL , -- domain entity info + `drill_down_dimensions` varchar(500) DEFAULT NULL , -- drill down dimensions info PRIMARY KEY (`id`) ); COMMENT ON TABLE s2_model IS 'model information'; @@ -110,6 +111,7 @@ CREATE TABLE IF NOT EXISTS `s2_metric` ( `data_format` varchar(500) DEFAULT NULL, `alias` varchar(500) DEFAULT NULL, `tags` varchar(500) DEFAULT NULL, + `relate_dimensions` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`) ); COMMENT ON TABLE s2_metric IS 'metric information table'; diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/LoadModelDataDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/LoadModelDataDemo.java index 4bf47d9a5..08a1ec2df 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/LoadModelDataDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/LoadModelDataDemo.java @@ -8,6 +8,7 @@ import com.tencent.supersonic.auth.api.authorization.service.AuthService; import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum; import com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum; import com.tencent.supersonic.common.pojo.enums.SensitiveLevelEnum; +import com.tencent.supersonic.semantic.api.model.enums.DataTypeEnum; import com.tencent.supersonic.semantic.api.model.enums.DimensionTypeEnum; import com.tencent.supersonic.semantic.api.model.enums.IdentifyTypeEnum; import com.tencent.supersonic.semantic.api.model.enums.SemanticTypeEnum; @@ -93,7 +94,7 @@ public class LoadModelDataDemo implements CommandLineRunner { DatabaseReq databaseReq = new DatabaseReq(); databaseReq.setName("H2数据实例"); databaseReq.setDescription("样例数据库实例"); - databaseReq.setType("h2"); + databaseReq.setType(DataTypeEnum.H2.getFeature()); databaseReq.setUrl("jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false"); databaseReq.setUsername("root"); databaseReq.setPassword("semantic"); diff --git a/launchers/standalone/src/main/resources/db/schema-h2.sql b/launchers/standalone/src/main/resources/db/schema-h2.sql index 087686e7e..77ec86bc1 100644 --- a/launchers/standalone/src/main/resources/db/schema-h2.sql +++ b/launchers/standalone/src/main/resources/db/schema-h2.sql @@ -129,6 +129,7 @@ CREATE TABLE IF NOT EXISTS `s2_model` ( `viewer` varchar(3000) DEFAULT NULL , -- domain available users `view_org` varchar(3000) DEFAULT NULL , -- domain available organization `entity` varchar(500) DEFAULT NULL , -- domain entity info + `drill_down_dimensions` varchar(500) DEFAULT NULL , -- drill down dimensions info PRIMARY KEY (`id`) ); COMMENT ON TABLE s2_model IS 'model information'; @@ -192,6 +193,7 @@ CREATE TABLE IF NOT EXISTS `s2_metric` ( `data_format` varchar(500) DEFAULT NULL, `alias` varchar(500) DEFAULT NULL, `tags` varchar(500) DEFAULT NULL, + `relate_dimensions` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`) ); COMMENT ON TABLE s2_metric IS 'metric information table'; diff --git a/launchers/standalone/src/main/resources/db/schema-mysql.sql b/launchers/standalone/src/main/resources/db/schema-mysql.sql index 266c67ff6..3e6ff801d 100644 --- a/launchers/standalone/src/main/resources/db/schema-mysql.sql +++ b/launchers/standalone/src/main/resources/db/schema-mysql.sql @@ -255,6 +255,7 @@ CREATE TABLE `s2_metric` ( `data_format` varchar(500) DEFAULT NULL COMMENT '数值类型参数', `alias` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, `tags` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, + `relate_dimensions` varchar(500) DEFAULT NULL COMMENT '指标相关维度', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='指标表'; @@ -275,6 +276,7 @@ CREATE TABLE `s2_model` ( `updated_by` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `updated_at` datetime DEFAULT NULL, `entity` text COLLATE utf8_unicode_ci, + `drill_down_dimensions` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/launchers/standalone/src/main/resources/db/sql-update.sql b/launchers/standalone/src/main/resources/db/sql-update.sql index 7799b3656..d43478c5e 100644 --- a/launchers/standalone/src/main/resources/db/sql-update.sql +++ b/launchers/standalone/src/main/resources/db/sql-update.sql @@ -54,4 +54,8 @@ ALTER TABLE s2_model add alias varchar(200) default null after domain_id; alter table s2_metric add tags varchar(500) null; --20230920 -alter table s2_user add is_admin int null; \ No newline at end of file +alter table s2_user add is_admin int null; + +--20230926 +alter table s2_model add drill_down_dimensions varchar(500) null; +alter table s2_metric add relate_dimensions varchar(500) null; \ No newline at end of file diff --git a/launchers/standalone/src/test/resources/db/schema-h2.sql b/launchers/standalone/src/test/resources/db/schema-h2.sql index 33429ca0b..5da8f62d2 100644 --- a/launchers/standalone/src/test/resources/db/schema-h2.sql +++ b/launchers/standalone/src/test/resources/db/schema-h2.sql @@ -144,6 +144,7 @@ CREATE TABLE IF NOT EXISTS `s2_model` ( `viewer` varchar(3000) DEFAULT NULL , -- domain available users `view_org` varchar(3000) DEFAULT NULL , -- domain available organization `entity` varchar(500) DEFAULT NULL , -- domain entity info + `drill_down_dimensions` varchar(500) DEFAULT NULL , -- drill down dimensions info PRIMARY KEY (`id`) ); COMMENT ON TABLE s2_model IS 'model information'; @@ -207,6 +208,7 @@ CREATE TABLE IF NOT EXISTS `s2_metric` ( `data_format` varchar(500) DEFAULT NULL, `alias` varchar(500) DEFAULT NULL, `tags` varchar(500) DEFAULT NULL, + `relate_dimensions` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`) ); COMMENT ON TABLE s2_metric IS 'metric information table'; diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/DrillDownDimension.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/DrillDownDimension.java new file mode 100644 index 000000000..23024ebdf --- /dev/null +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/DrillDownDimension.java @@ -0,0 +1,16 @@ +package com.tencent.supersonic.semantic.api.model.pojo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DrillDownDimension { + + private Long dimensionId; + + private boolean necessary; + +} \ No newline at end of file diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/Measure.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/Measure.java index a6c028f46..00cfc89d5 100644 --- a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/Measure.java +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/Measure.java @@ -34,4 +34,9 @@ public class Measure { this.isCreateMetric = isCreateMetric; this.bizName = bizName; } + + public Measure(String bizName, Long datasourceId) { + this.bizName = bizName; + this.datasourceId = datasourceId; + } } diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/RelateDimension.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/RelateDimension.java new file mode 100644 index 000000000..9e1e82ec5 --- /dev/null +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/pojo/RelateDimension.java @@ -0,0 +1,17 @@ +package com.tencent.supersonic.semantic.api.model.pojo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class RelateDimension { + + List drillDownDimensions; + +} diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/MetricBaseReq.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/MetricBaseReq.java index 7481d997d..c47c11f15 100644 --- a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/MetricBaseReq.java +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/MetricBaseReq.java @@ -1,6 +1,6 @@ package com.tencent.supersonic.semantic.api.model.request; - +import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; import com.tencent.supersonic.common.pojo.DataFormat; import lombok.Data; @@ -20,4 +20,6 @@ public class MetricBaseReq extends SchemaItem { private List tags; + private RelateDimension relateDimension; + } diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/ModelReq.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/ModelReq.java index 20413eb79..12f087c51 100644 --- a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/ModelReq.java +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/request/ModelReq.java @@ -1,6 +1,7 @@ package com.tencent.supersonic.semantic.api.model.request; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.pojo.Entity; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; import lombok.Data; @@ -27,4 +28,6 @@ public class ModelReq extends SchemaItem { private List adminOrgs = new ArrayList<>(); private Entity entity; + + private List drillDownDimensions; } diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/MetricResp.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/MetricResp.java index 4307006ad..a3f9b8e44 100644 --- a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/MetricResp.java +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/MetricResp.java @@ -4,6 +4,7 @@ package com.tencent.supersonic.semantic.api.model.response; import com.google.common.collect.Lists; import com.tencent.supersonic.common.pojo.DataFormat; import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams; +import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; import lombok.Data; import lombok.ToString; @@ -35,6 +36,8 @@ public class MetricResp extends SchemaItem { private List tags; + private RelateDimension relateDimension; + private boolean hasAdminRes = false; private String defaultAgg; diff --git a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/ModelResp.java b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/ModelResp.java index a6337881c..9d9574a5b 100644 --- a/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/ModelResp.java +++ b/semantic/api/src/main/java/com/tencent/supersonic/semantic/api/model/response/ModelResp.java @@ -1,5 +1,6 @@ package com.tencent.supersonic.semantic.api.model.response; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.pojo.Entity; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; import lombok.Data; @@ -33,6 +34,8 @@ public class ModelResp extends SchemaItem { private String fullPath; + private List drillDownDimensions; + public boolean openToAll() { return isOpen != null && isOpen == 1; } diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/MetricServiceImpl.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/MetricServiceImpl.java index ddaeec94a..af8d67858 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/MetricServiceImpl.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/MetricServiceImpl.java @@ -13,6 +13,7 @@ import com.tencent.supersonic.common.pojo.enums.AuthType; import com.tencent.supersonic.common.pojo.enums.DictWordType; import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException; import com.tencent.supersonic.common.util.ChatGptHelper; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.pojo.Measure; import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams; import com.tencent.supersonic.semantic.api.model.request.MetricReq; @@ -29,6 +30,8 @@ import com.tencent.supersonic.semantic.model.domain.repository.MetricRepository; import com.tencent.supersonic.semantic.model.domain.utils.MetricConverter; import com.tencent.supersonic.semantic.model.domain.MetricService; import com.tencent.supersonic.semantic.model.domain.pojo.Metric; + +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -186,6 +189,14 @@ public class MetricServiceImpl implements MetricService { return metricResp; } + private MetricResp getMetric(Long id) { + MetricDO metricDO = metricRepository.getMetricById(id); + if (metricDO == null) { + return null; + } + return MetricConverter.convert2MetricResp(metricDO, new HashMap<>()); + } + @Override public void updateExprMetric(MetricReq metricReq, User user) { preCheckMetric(metricReq); @@ -286,6 +297,19 @@ public class MetricServiceImpl implements MetricService { metricResp.getTags().stream()).collect(Collectors.toSet()); } + @Override + public List getDrillDownDimension(Long metricId) { + MetricResp metricResp = getMetric(metricId); + if (metricResp == null) { + return Lists.newArrayList(); + } + if (metricResp.getRelateDimension() != null + && !CollectionUtils.isEmpty(metricResp.getRelateDimension().getDrillDownDimensions())) { + return metricResp.getRelateDimension().getDrillDownDimensions(); + } + ModelResp modelResp = modelService.getModel(metricResp.getModelId()); + return modelResp.getDrillDownDimensions(); + } private void saveMetricBatch(List metrics, User user) { if (CollectionUtils.isEmpty(metrics)) { diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/ModelServiceImpl.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/ModelServiceImpl.java index 3a26ec9c8..9ef0b75d7 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/ModelServiceImpl.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/application/ModelServiceImpl.java @@ -7,6 +7,7 @@ import com.tencent.supersonic.auth.api.authentication.service.UserService; import com.tencent.supersonic.common.pojo.enums.AuthType; import com.tencent.supersonic.common.util.BeanMapper; import com.tencent.supersonic.common.util.JsonUtil; +import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension; import com.tencent.supersonic.semantic.api.model.request.ModelReq; import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq; import com.tencent.supersonic.semantic.api.model.response.DatabaseResp; @@ -75,7 +76,7 @@ public class ModelServiceImpl implements ModelService { @Override public void createModel(ModelReq modelReq, User user) { - log.info("[create model] cmd : {}", JSONObject.toJSONString(modelReq)); + log.info("[create model] req : {}", JSONObject.toJSONString(modelReq)); Model model = ModelConvert.convert(modelReq); log.info("[create model] object:{}", JSONObject.toJSONString(modelReq)); saveModel(model, user); @@ -261,7 +262,7 @@ public class ModelServiceImpl implements ModelService { ModelSchemaResp modelSchemaResp = new ModelSchemaResp(); BeanUtils.copyProperties(modelResp, modelSchemaResp); modelSchemaResp.setDimensions(generateDimSchema(modelId)); - modelSchemaResp.setMetrics(generateMetricSchema(modelId)); + modelSchemaResp.setMetrics(generateMetricSchema(modelId, modelResp)); return modelSchemaResp; } @@ -292,7 +293,7 @@ public class ModelServiceImpl implements ModelService { List measureResps = measureRespsMap.getOrDefault(modelId, Lists.newArrayList()); List metricResps = metricRespMap.getOrDefault(modelId, Lists.newArrayList()); List metricSchemaResps = metricResps.stream().map(metricResp -> - convert(metricResp, metricResps, measureResps)).collect(Collectors.toList()); + convert(metricResp, metricResps, measureResps, modelResp)).collect(Collectors.toList()); List dimensionResps = dimensionRespsMap.getOrDefault(modelId, Lists.newArrayList()) .stream().map(this::convert).collect(Collectors.toList()); ModelSchemaResp modelSchemaResp = new ModelSchemaResp(); @@ -314,12 +315,12 @@ public class ModelServiceImpl implements ModelService { return null; } - private List generateMetricSchema(Long modelId) { + private List generateMetricSchema(Long modelId, ModelResp modelResp) { List metricSchemaDescList = new ArrayList<>(); List metricResps = metricService.getMetrics(modelId); List measureResps = datasourceService.getMeasureListOfModel(modelId); metricResps.stream().forEach(metricResp -> - metricSchemaDescList.add(convert(metricResp, metricResps, measureResps))); + metricSchemaDescList.add(convert(metricResp, metricResps, measureResps, modelResp))); return metricSchemaDescList; } @@ -336,9 +337,14 @@ public class ModelServiceImpl implements ModelService { } private MetricSchemaResp convert(MetricResp metricResp, List metricResps, - List measureResps) { + List measureResps, ModelResp modelResp) { MetricSchemaResp metricSchemaResp = new MetricSchemaResp(); BeanUtils.copyProperties(metricResp, metricSchemaResp); + RelateDimension relateDimension = metricResp.getRelateDimension(); + if (relateDimension == null || CollectionUtils.isEmpty(relateDimension.getDrillDownDimensions())) { + metricSchemaResp.setRelateDimension(RelateDimension.builder() + .drillDownDimensions(modelResp.getDrillDownDimensions()).build()); + } metricSchemaResp.setUseCnt(0L); String agg = catalog.getAgg(metricResps, measureResps, metricSchemaResp.getBizName()); metricSchemaResp.setDefaultAgg(agg); diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/MetricService.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/MetricService.java index cd2dc4c15..c079414bd 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/MetricService.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/MetricService.java @@ -2,6 +2,7 @@ package com.tencent.supersonic.semantic.model.domain; import com.github.pagehelper.PageInfo; import com.tencent.supersonic.auth.api.authentication.pojo.User; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.request.MetricReq; import com.tencent.supersonic.semantic.api.model.request.PageMetricReq; import com.tencent.supersonic.semantic.api.model.response.MetricResp; @@ -40,4 +41,6 @@ public interface MetricService { List mockAlias(MetricReq metricReq, String mockType, User user); Set getMetricTags(); + + List getDrillDownDimension(Long metricId); } diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDO.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDO.java index 098e63945..03d211f91 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDO.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDO.java @@ -83,6 +83,11 @@ public class MetricDO { */ private String tags; + /** + * + */ + private String relateDimensions; + /** * 类型参数 */ @@ -344,6 +349,22 @@ public class MetricDO { this.tags = tags == null ? null : tags.trim(); } + /** + * + * @return relate_dimensions + */ + public String getRelateDimensions() { + return relateDimensions; + } + + /** + * + * @param relateDimensions + */ + public void setRelateDimensions(String relateDimensions) { + this.relateDimensions = relateDimensions == null ? null : relateDimensions.trim(); + } + /** * 类型参数 * @return type_params 类型参数 diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDOExample.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDOExample.java index d57855cfe..e49e7c06e 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDOExample.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/MetricDOExample.java @@ -1262,6 +1262,76 @@ public class MetricDOExample { addCriterion("tags not between", value1, value2, "tags"); return (Criteria) this; } + + public Criteria andRelateDimensionsIsNull() { + addCriterion("relate_dimensions is null"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsIsNotNull() { + addCriterion("relate_dimensions is not null"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsEqualTo(String value) { + addCriterion("relate_dimensions =", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsNotEqualTo(String value) { + addCriterion("relate_dimensions <>", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsGreaterThan(String value) { + addCriterion("relate_dimensions >", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsGreaterThanOrEqualTo(String value) { + addCriterion("relate_dimensions >=", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsLessThan(String value) { + addCriterion("relate_dimensions <", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsLessThanOrEqualTo(String value) { + addCriterion("relate_dimensions <=", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsLike(String value) { + addCriterion("relate_dimensions like", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsNotLike(String value) { + addCriterion("relate_dimensions not like", value, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsIn(List values) { + addCriterion("relate_dimensions in", values, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsNotIn(List values) { + addCriterion("relate_dimensions not in", values, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsBetween(String value1, String value2) { + addCriterion("relate_dimensions between", value1, value2, "relateDimensions"); + return (Criteria) this; + } + + public Criteria andRelateDimensionsNotBetween(String value1, String value2) { + addCriterion("relate_dimensions not between", value1, value2, "relateDimensions"); + return (Criteria) this; + } } /** diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDO.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDO.java index b05e1a7a9..974011a68 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDO.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDO.java @@ -73,6 +73,11 @@ public class ModelDO { */ private Date updatedAt; + /** + * + */ + private String drillDownDimensions; + /** * */ @@ -302,6 +307,22 @@ public class ModelDO { this.updatedAt = updatedAt; } + /** + * + * @return drill_down_dimensions + */ + public String getDrillDownDimensions() { + return drillDownDimensions; + } + + /** + * + * @param drillDownDimensions + */ + public void setDrillDownDimensions(String drillDownDimensions) { + this.drillDownDimensions = drillDownDimensions == null ? null : drillDownDimensions.trim(); + } + /** * * @return entity diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDOExample.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDOExample.java index 9744d7b39..fea82e508 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDOExample.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/dataobject/ModelDOExample.java @@ -1132,6 +1132,76 @@ public class ModelDOExample { addCriterion("updated_at not between", value1, value2, "updatedAt"); return (Criteria) this; } + + public Criteria andDrillDownDimensionsIsNull() { + addCriterion("drill_down_dimensions is null"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsIsNotNull() { + addCriterion("drill_down_dimensions is not null"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsEqualTo(String value) { + addCriterion("drill_down_dimensions =", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsNotEqualTo(String value) { + addCriterion("drill_down_dimensions <>", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsGreaterThan(String value) { + addCriterion("drill_down_dimensions >", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsGreaterThanOrEqualTo(String value) { + addCriterion("drill_down_dimensions >=", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsLessThan(String value) { + addCriterion("drill_down_dimensions <", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsLessThanOrEqualTo(String value) { + addCriterion("drill_down_dimensions <=", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsLike(String value) { + addCriterion("drill_down_dimensions like", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsNotLike(String value) { + addCriterion("drill_down_dimensions not like", value, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsIn(List values) { + addCriterion("drill_down_dimensions in", values, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsNotIn(List values) { + addCriterion("drill_down_dimensions not in", values, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsBetween(String value1, String value2) { + addCriterion("drill_down_dimensions between", value1, value2, "drillDownDimensions"); + return (Criteria) this; + } + + public Criteria andDrillDownDimensionsNotBetween(String value1, String value2) { + addCriterion("drill_down_dimensions not between", value1, value2, "drillDownDimensions"); + return (Criteria) this; + } } /** diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Metric.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Metric.java index cfdc4917d..9d45e57d1 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Metric.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Metric.java @@ -2,6 +2,7 @@ package com.tencent.supersonic.semantic.model.domain.pojo; import com.tencent.supersonic.common.pojo.DataFormat; import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams; +import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; import lombok.Data; import org.apache.commons.lang3.StringUtils; @@ -27,6 +28,8 @@ public class Metric extends SchemaItem { private List tags; + private RelateDimension relateDimension; + public String getTag() { if (CollectionUtils.isEmpty(tags)) { return ""; diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Model.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Model.java index 971919bc2..1a1e8fb4b 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Model.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/pojo/Model.java @@ -1,13 +1,10 @@ package com.tencent.supersonic.semantic.model.domain.pojo; -import com.tencent.supersonic.common.pojo.enums.StatusEnum; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.pojo.Entity; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; -import com.tencent.supersonic.semantic.api.model.request.ModelReq; import lombok.Data; -import org.springframework.beans.BeanUtils; - import java.util.List; @@ -30,12 +27,6 @@ public class Model extends SchemaItem { private Entity entity; - public static Model create(ModelReq modelReq) { - Model model = new Model(); - BeanUtils.copyProperties(modelReq, model); - model.setStatus(StatusEnum.ONLINE.getCode()); - return model; - } - + private List drillDownDimensions; } diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/MetricConverter.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/MetricConverter.java index 5573c7b87..8f194f6ac 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/MetricConverter.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/MetricConverter.java @@ -5,6 +5,7 @@ import com.google.common.collect.Lists; import com.tencent.supersonic.common.pojo.DataFormat; import com.tencent.supersonic.semantic.api.model.pojo.Measure; import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams; +import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension; import com.tencent.supersonic.semantic.api.model.response.ModelResp; import com.tencent.supersonic.semantic.api.model.yaml.MeasureYamlTpl; import com.tencent.supersonic.semantic.api.model.yaml.MetricTypeParamsYamlTpl; @@ -37,6 +38,9 @@ public class MetricConverter { if (metric.getDataFormat() != null) { metricDO.setDataFormat(JSONObject.toJSONString(metric.getDataFormat())); } + if (metric.getRelateDimension() != null) { + metricDO.setRelateDimensions(JSONObject.toJSONString(metric.getRelateDimension())); + } metricDO.setTags(metric.getTag()); return metricDO; } @@ -53,6 +57,7 @@ public class MetricConverter { metricDO.setTypeParams(JSONObject.toJSONString(metric.getTypeParams())); metricDO.setDataFormat(JSONObject.toJSONString(metric.getDataFormat())); metricDO.setTags(metric.getTag()); + metricDO.setRelateDimensions(JSONObject.toJSONString(metric.getRelateDimension())); return metricDO; } @@ -68,6 +73,8 @@ public class MetricConverter { metricResp.setDomainId(modelResp.getDomainId()); } metricResp.setTag(metricDO.getTags()); + metricResp.setRelateDimension(JSONObject.parseObject(metricDO.getRelateDimensions(), + RelateDimension.class)); return metricResp; } diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/ModelConvert.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/ModelConvert.java index d0f8794b5..8c5c80a6b 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/ModelConvert.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/domain/utils/ModelConvert.java @@ -5,6 +5,7 @@ import com.google.common.collect.Lists; import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.common.pojo.enums.StatusEnum; import com.tencent.supersonic.common.util.JsonUtil; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.pojo.Entity; import com.tencent.supersonic.semantic.api.model.request.ModelReq; import com.tencent.supersonic.semantic.api.model.response.DomainResp; @@ -38,6 +39,7 @@ public class ModelConvert { modelDO.setViewer(String.join(",", model.getViewers())); modelDO.setViewOrg(String.join(",", model.getViewOrgs())); modelDO.setEntity(JsonUtil.toString(model.getEntity())); + modelDO.setDrillDownDimensions(JsonUtil.toString(model.getDrillDownDimensions())); return modelDO; } @@ -53,6 +55,7 @@ public class ModelConvert { modelResp.setViewOrgs(StringUtils.isBlank(modelDO.getViewOrg()) ? Lists.newArrayList() : Arrays.asList(modelDO.getViewOrg().split(","))); modelResp.setEntity(JsonUtil.toObject(modelDO.getEntity(), Entity.class)); + modelResp.setDrillDownDimensions(JsonUtil.toList(modelDO.getDrillDownDimensions(), DrillDownDimension.class)); return modelResp; } diff --git a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/rest/MetricController.java b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/rest/MetricController.java index 4b60bfab2..1267f58ad 100644 --- a/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/rest/MetricController.java +++ b/semantic/model/src/main/java/com/tencent/supersonic/semantic/model/rest/MetricController.java @@ -4,6 +4,7 @@ package com.tencent.supersonic.semantic.model.rest; import com.github.pagehelper.PageInfo; import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.utils.UserHolder; +import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension; import com.tencent.supersonic.semantic.api.model.request.MetricReq; import com.tencent.supersonic.semantic.api.model.request.PageMetricReq; import com.tencent.supersonic.semantic.api.model.response.MetricResp; @@ -99,4 +100,9 @@ public class MetricController { return metricService.getMetricTags(); } + + @GetMapping("/getDrillDownDimension") + public List getDrillDownDimension(Long metricId) { + return metricService.getDrillDownDimension(metricId); + } } diff --git a/semantic/model/src/main/resources/mapper/MetricDOMapper.xml b/semantic/model/src/main/resources/mapper/MetricDOMapper.xml index 2d20f9ee8..e2e1ffbba 100644 --- a/semantic/model/src/main/resources/mapper/MetricDOMapper.xml +++ b/semantic/model/src/main/resources/mapper/MetricDOMapper.xml @@ -18,6 +18,7 @@ + @@ -53,7 +54,7 @@ id, model_id, name, biz_name, description, status, sensitive_level, type, created_at, - created_by, updated_at, updated_by, data_format_type, data_format, alias, tags + created_by, updated_at, updated_by, data_format_type, data_format, alias, tags, relate_dimensions type_params @@ -109,13 +110,15 @@ sensitive_level, type, created_at, created_by, updated_at, updated_by, data_format_type, data_format, alias, - tags, type_params) + tags, relate_dimensions, type_params + ) values (#{id,jdbcType=BIGINT}, #{modelId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{bizName,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{sensitiveLevel,jdbcType=INTEGER}, #{type,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR}, #{updatedAt,jdbcType=TIMESTAMP}, #{updatedBy,jdbcType=VARCHAR}, #{dataFormatType,jdbcType=VARCHAR}, #{dataFormat,jdbcType=VARCHAR}, #{alias,jdbcType=VARCHAR}, - #{tags,jdbcType=VARCHAR}, #{typeParams,jdbcType=LONGVARCHAR}) + #{tags,jdbcType=VARCHAR}, #{relateDimensions,jdbcType=VARCHAR}, #{typeParams,jdbcType=LONGVARCHAR} + ) insert into s2_metric @@ -168,6 +171,9 @@ tags, + + relate_dimensions, + type_params, @@ -221,6 +227,9 @@ #{tags,jdbcType=VARCHAR}, + + #{relateDimensions,jdbcType=VARCHAR}, + #{typeParams,jdbcType=LONGVARCHAR}, @@ -280,6 +289,9 @@ tags = #{tags,jdbcType=VARCHAR}, + + relate_dimensions = #{relateDimensions,jdbcType=VARCHAR}, + type_params = #{typeParams,jdbcType=LONGVARCHAR}, @@ -303,6 +315,7 @@ data_format = #{dataFormat,jdbcType=VARCHAR}, alias = #{alias,jdbcType=VARCHAR}, tags = #{tags,jdbcType=VARCHAR}, + relate_dimensions = #{relateDimensions,jdbcType=VARCHAR}, type_params = #{typeParams,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=BIGINT} @@ -322,7 +335,8 @@ data_format_type = #{dataFormatType,jdbcType=VARCHAR}, data_format = #{dataFormat,jdbcType=VARCHAR}, alias = #{alias,jdbcType=VARCHAR}, - tags = #{tags,jdbcType=VARCHAR} + tags = #{tags,jdbcType=VARCHAR}, + relate_dimensions = #{relateDimensions,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} \ No newline at end of file diff --git a/semantic/model/src/main/resources/mapper/ModelDOMapper.xml b/semantic/model/src/main/resources/mapper/ModelDOMapper.xml index 85ae94f2d..f4048bf59 100644 --- a/semantic/model/src/main/resources/mapper/ModelDOMapper.xml +++ b/semantic/model/src/main/resources/mapper/ModelDOMapper.xml @@ -16,6 +16,7 @@ + @@ -80,7 +81,7 @@ id, name, biz_name, domain_id, alias, viewer, view_org, admin, admin_org, is_open, - created_by, created_at, updated_by, updated_at + created_by, created_at, updated_by, updated_at, drill_down_dimensions entity @@ -135,14 +136,14 @@ domain_id, alias, viewer, view_org, admin, admin_org, is_open, created_by, created_at, - updated_by, updated_at, entity - ) + updated_by, updated_at, drill_down_dimensions, + entity) values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{bizName,jdbcType=VARCHAR}, #{domainId,jdbcType=BIGINT}, #{alias,jdbcType=VARCHAR}, #{viewer,jdbcType=VARCHAR}, #{viewOrg,jdbcType=VARCHAR}, #{admin,jdbcType=VARCHAR}, #{adminOrg,jdbcType=VARCHAR}, #{isOpen,jdbcType=INTEGER}, #{createdBy,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, - #{updatedBy,jdbcType=VARCHAR}, #{updatedAt,jdbcType=TIMESTAMP}, #{entity,jdbcType=LONGVARCHAR} - ) + #{updatedBy,jdbcType=VARCHAR}, #{updatedAt,jdbcType=TIMESTAMP}, #{drillDownDimensions,jdbcType=VARCHAR}, + #{entity,jdbcType=LONGVARCHAR}) insert into s2_model @@ -189,6 +190,9 @@ updated_at, + + drill_down_dimensions, + entity, @@ -236,6 +240,9 @@ #{updatedAt,jdbcType=TIMESTAMP}, + + #{drillDownDimensions,jdbcType=VARCHAR}, + #{entity,jdbcType=LONGVARCHAR}, @@ -292,6 +299,9 @@ updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}, + + drill_down_dimensions = #{record.drillDownDimensions,jdbcType=VARCHAR}, + entity = #{record.entity,jdbcType=LONGVARCHAR}, @@ -316,6 +326,7 @@ created_at = #{record.createdAt,jdbcType=TIMESTAMP}, updated_by = #{record.updatedBy,jdbcType=VARCHAR}, updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}, + drill_down_dimensions = #{record.drillDownDimensions,jdbcType=VARCHAR}, entity = #{record.entity,jdbcType=LONGVARCHAR} @@ -336,7 +347,8 @@ created_by = #{record.createdBy,jdbcType=VARCHAR}, created_at = #{record.createdAt,jdbcType=TIMESTAMP}, updated_by = #{record.updatedBy,jdbcType=VARCHAR}, - updated_at = #{record.updatedAt,jdbcType=TIMESTAMP} + updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}, + drill_down_dimensions = #{record.drillDownDimensions,jdbcType=VARCHAR} @@ -383,6 +395,9 @@ updated_at = #{updatedAt,jdbcType=TIMESTAMP}, + + drill_down_dimensions = #{drillDownDimensions,jdbcType=VARCHAR}, + entity = #{entity,jdbcType=LONGVARCHAR}, @@ -404,6 +419,7 @@ created_at = #{createdAt,jdbcType=TIMESTAMP}, updated_by = #{updatedBy,jdbcType=VARCHAR}, updated_at = #{updatedAt,jdbcType=TIMESTAMP}, + drill_down_dimensions = #{drillDownDimensions,jdbcType=VARCHAR}, entity = #{entity,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=BIGINT} @@ -421,7 +437,8 @@ created_by = #{createdBy,jdbcType=VARCHAR}, created_at = #{createdAt,jdbcType=TIMESTAMP}, updated_by = #{updatedBy,jdbcType=VARCHAR}, - updated_at = #{updatedAt,jdbcType=TIMESTAMP} + updated_at = #{updatedAt,jdbcType=TIMESTAMP}, + drill_down_dimensions = #{drillDownDimensions,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} \ No newline at end of file