mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-10 19:51:00 +00:00
(improvement)(headless) transfer term nature modelId to viewId before providing it to chat and put the modelId of metadata into the dict word instead of viewId (#739)
Co-authored-by: jolunoluo
This commit is contained in:
@@ -45,7 +45,8 @@ public class GroupByCorrector extends BaseSemanticCorrector {
|
|||||||
ViewResp viewResp = viewService.getView(viewId);
|
ViewResp viewResp = viewService.getView(viewId);
|
||||||
List<Long> modelIds = viewResp.getViewDetail().getViewModelConfigs().stream().map(config -> config.getId())
|
List<Long> modelIds = viewResp.getViewDetail().getViewModelConfigs().stream().map(config -> config.getId())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
MetaFilter metaFilter = new MetaFilter(modelIds);
|
MetaFilter metaFilter = new MetaFilter();
|
||||||
|
metaFilter.setIds(modelIds);
|
||||||
List<ModelResp> modelRespList = modelService.getModelList(metaFilter);
|
List<ModelResp> modelRespList = modelService.getModelList(metaFilter);
|
||||||
for (ModelResp modelResp : modelRespList) {
|
for (ModelResp modelResp : modelRespList) {
|
||||||
List<Dim> dimList = modelResp.getModelDetail().getDimensions();
|
List<Dim> dimList = modelResp.getModelDetail().getDimensions();
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ import com.tencent.supersonic.headless.api.pojo.response.S2Term;
|
|||||||
import com.tencent.supersonic.headless.core.knowledge.EmbeddingResult;
|
import com.tencent.supersonic.headless.core.knowledge.EmbeddingResult;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.builder.BaseWordBuilder;
|
import com.tencent.supersonic.headless.core.knowledge.builder.BaseWordBuilder;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.helper.HanlpHelper;
|
import com.tencent.supersonic.headless.core.knowledge.helper.HanlpHelper;
|
||||||
|
import com.tencent.supersonic.headless.server.service.KnowledgeService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* A mapper that recognizes schema elements with vector embedding.
|
* A mapper that recognizes schema elements with vector embedding.
|
||||||
@@ -24,7 +25,8 @@ public class EmbeddingMapper extends BaseMapper {
|
|||||||
public void doMap(QueryContext queryContext) {
|
public void doMap(QueryContext queryContext) {
|
||||||
//1. query from embedding by queryText
|
//1. query from embedding by queryText
|
||||||
String queryText = queryContext.getQueryText();
|
String queryText = queryContext.getQueryText();
|
||||||
List<S2Term> terms = HanlpHelper.getTerms(queryText);
|
KnowledgeService knowledgeService = ContextUtils.getBean(KnowledgeService.class);
|
||||||
|
List<S2Term> terms = knowledgeService.getTerms(queryText);
|
||||||
|
|
||||||
EmbeddingMatchStrategy matchStrategy = ContextUtils.getBean(EmbeddingMatchStrategy.class);
|
EmbeddingMatchStrategy matchStrategy = ContextUtils.getBean(EmbeddingMatchStrategy.class);
|
||||||
List<EmbeddingResult> matchResults = matchStrategy.getMatches(queryContext, terms);
|
List<EmbeddingResult> matchResults = matchStrategy.getMatches(queryContext, terms);
|
||||||
|
|||||||
@@ -1,36 +1,27 @@
|
|||||||
package com.tencent.supersonic.chat.core.parser.sql.llm;
|
package com.tencent.supersonic.chat.core.parser.sql.llm;
|
||||||
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
import com.tencent.supersonic.chat.api.pojo.ViewSchema;
|
||||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.response.ChatDefaultRichConfigResp;
|
|
||||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||||
import com.tencent.supersonic.common.util.DatePeriodEnum;
|
import com.tencent.supersonic.common.util.DatePeriodEnum;
|
||||||
import com.tencent.supersonic.common.util.DateUtils;
|
import com.tencent.supersonic.common.util.DateUtils;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.TimeDefaultConfig;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class S2SqlDateHelper {
|
public class S2SqlDateHelper {
|
||||||
|
|
||||||
public static String getReferenceDate(QueryContext queryContext, Long modelId) {
|
public static String getReferenceDate(QueryContext queryContext, Long viewId) {
|
||||||
String defaultDate = DateUtils.getBeforeDate(0);
|
String defaultDate = DateUtils.getBeforeDate(0);
|
||||||
if (Objects.isNull(modelId)) {
|
if (Objects.isNull(viewId)) {
|
||||||
return defaultDate;
|
return defaultDate;
|
||||||
}
|
}
|
||||||
ChatConfigFilter filter = new ChatConfigFilter();
|
ViewSchema viewSchema = queryContext.getSemanticSchema().getViewSchemaMap().get(viewId);
|
||||||
filter.setModelId(modelId);
|
if (viewSchema == null || viewSchema.getTagTypeTimeDefaultConfig() == null) {
|
||||||
ChatConfigRichResp chatConfigRichResp = queryContext.getModelIdToChatRichConfig().get(modelId);
|
|
||||||
|
|
||||||
if (Objects.isNull(chatConfigRichResp)) {
|
|
||||||
return defaultDate;
|
return defaultDate;
|
||||||
}
|
}
|
||||||
if (Objects.isNull(chatConfigRichResp.getChatDetailRichConfig()) || Objects.isNull(
|
TimeDefaultConfig tagTypeTimeDefaultConfig = viewSchema.getTagTypeTimeDefaultConfig();
|
||||||
chatConfigRichResp.getChatDetailRichConfig().getChatDefaultConfig())) {
|
Integer unit = tagTypeTimeDefaultConfig.getUnit();
|
||||||
return defaultDate;
|
String period = tagTypeTimeDefaultConfig.getPeriod();
|
||||||
}
|
|
||||||
|
|
||||||
ChatDefaultRichConfigResp chatDefaultConfig = chatConfigRichResp.getChatDetailRichConfig()
|
|
||||||
.getChatDefaultConfig();
|
|
||||||
Integer unit = chatDefaultConfig.getUnit();
|
|
||||||
String period = chatDefaultConfig.getPeriod();
|
|
||||||
if (Objects.nonNull(unit)) {
|
if (Objects.nonNull(unit)) {
|
||||||
// If the unit is set to less than 0, then do not add relative date.
|
// If the unit is set to less than 0, then do not add relative date.
|
||||||
if (unit < 0) {
|
if (unit < 0) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class ViewSchemaBuilder {
|
|||||||
|
|
||||||
SchemaElement metricToAdd = SchemaElement.builder()
|
SchemaElement metricToAdd = SchemaElement.builder()
|
||||||
.view(resp.getId())
|
.view(resp.getId())
|
||||||
|
.model(metric.getModelId())
|
||||||
.id(metric.getId())
|
.id(metric.getId())
|
||||||
.name(metric.getName())
|
.name(metric.getName())
|
||||||
.bizName(metric.getBizName())
|
.bizName(metric.getBizName())
|
||||||
@@ -84,6 +85,7 @@ public class ViewSchemaBuilder {
|
|||||||
}
|
}
|
||||||
SchemaElement dimToAdd = SchemaElement.builder()
|
SchemaElement dimToAdd = SchemaElement.builder()
|
||||||
.view(resp.getId())
|
.view(resp.getId())
|
||||||
|
.model(dim.getModelId())
|
||||||
.id(dim.getId())
|
.id(dim.getId())
|
||||||
.name(dim.getName())
|
.name(dim.getName())
|
||||||
.bizName(dim.getBizName())
|
.bizName(dim.getBizName())
|
||||||
@@ -96,6 +98,7 @@ public class ViewSchemaBuilder {
|
|||||||
|
|
||||||
SchemaElement dimValueToAdd = SchemaElement.builder()
|
SchemaElement dimValueToAdd = SchemaElement.builder()
|
||||||
.view(resp.getId())
|
.view(resp.getId())
|
||||||
|
.model(dim.getModelId())
|
||||||
.id(dim.getId())
|
.id(dim.getId())
|
||||||
.name(dim.getName())
|
.name(dim.getName())
|
||||||
.bizName(dim.getBizName())
|
.bizName(dim.getBizName())
|
||||||
@@ -107,6 +110,7 @@ public class ViewSchemaBuilder {
|
|||||||
if (dim.getIsTag() == 1) {
|
if (dim.getIsTag() == 1) {
|
||||||
SchemaElement tagToAdd = SchemaElement.builder()
|
SchemaElement tagToAdd = SchemaElement.builder()
|
||||||
.view(resp.getId())
|
.view(resp.getId())
|
||||||
|
.model(dim.getModelId())
|
||||||
.id(dim.getId())
|
.id(dim.getId())
|
||||||
.name(dim.getName())
|
.name(dim.getName())
|
||||||
.bizName(dim.getBizName())
|
.bizName(dim.getBizName())
|
||||||
@@ -126,6 +130,7 @@ public class ViewSchemaBuilder {
|
|||||||
if (dim != null) {
|
if (dim != null) {
|
||||||
SchemaElement entity = SchemaElement.builder()
|
SchemaElement entity = SchemaElement.builder()
|
||||||
.view(resp.getId())
|
.view(resp.getId())
|
||||||
|
.model(dim.getModelId())
|
||||||
.id(dim.getId())
|
.id(dim.getId())
|
||||||
.name(dim.getName())
|
.name(dim.getName())
|
||||||
.bizName(dim.getBizName())
|
.bizName(dim.getBizName())
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ public class DimensionRecommendProcessor implements ExecuteResultProcessor {
|
|||||||
queryResult.setRecommendedDimensions(dimensionRecommended);
|
queryResult.setRecommendedDimensions(dimensionRecommended);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SchemaElement> getDimensions(Long metricId, Long modelId) {
|
private List<SchemaElement> getDimensions(Long metricId, Long viewId) {
|
||||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||||
ViewSchema modelSchema = semanticService.getModelSchema(modelId);
|
ViewSchema viewSchema = semanticService.getViewSchema(viewId);
|
||||||
List<Long> drillDownDimensions = Lists.newArrayList();
|
List<Long> drillDownDimensions = Lists.newArrayList();
|
||||||
Set<SchemaElement> metricElements = modelSchema.getMetrics();
|
Set<SchemaElement> metricElements = viewSchema.getMetrics();
|
||||||
if (!CollectionUtils.isEmpty(metricElements)) {
|
if (!CollectionUtils.isEmpty(metricElements)) {
|
||||||
Optional<SchemaElement> metric = metricElements.stream().filter(schemaElement ->
|
Optional<SchemaElement> metric = metricElements.stream().filter(schemaElement ->
|
||||||
metricId.equals(schemaElement.getId())
|
metricId.equals(schemaElement.getId())
|
||||||
@@ -54,7 +54,7 @@ public class DimensionRecommendProcessor implements ExecuteResultProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final List<Long> drillDownDimensionsFinal = drillDownDimensions;
|
final List<Long> drillDownDimensionsFinal = drillDownDimensions;
|
||||||
return modelSchema.getDimensions().stream()
|
return viewSchema.getDimensions().stream()
|
||||||
.filter(dim -> filterDimension(drillDownDimensionsFinal, dim))
|
.filter(dim -> filterDimension(drillDownDimensionsFinal, dim))
|
||||||
.sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed())
|
.sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed())
|
||||||
.limit(recommend_dimension_size)
|
.limit(recommend_dimension_size)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class SemanticService {
|
|||||||
return schemaService.getSemanticSchema();
|
return schemaService.getSemanticSchema();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewSchema getModelSchema(Long id) {
|
public ViewSchema getViewSchema(Long id) {
|
||||||
return schemaService.getViewSchema(id);
|
return schemaService.getViewSchema(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ public class ConfigServiceImpl implements ConfigService {
|
|||||||
}
|
}
|
||||||
BeanUtils.copyProperties(chatConfigResp, chatConfigRich);
|
BeanUtils.copyProperties(chatConfigResp, chatConfigRich);
|
||||||
|
|
||||||
ViewSchema viewSchema = semanticService.getModelSchema(modelId);
|
ViewSchema viewSchema = semanticService.getViewSchema(modelId);
|
||||||
if (viewSchema == null) {
|
if (viewSchema == null) {
|
||||||
return chatConfigRich;
|
return chatConfigRich;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class RecommendServiceImpl implements RecommendService {
|
|||||||
if (Objects.isNull(modelId)) {
|
if (Objects.isNull(modelId)) {
|
||||||
return new RecommendResp();
|
return new RecommendResp();
|
||||||
}
|
}
|
||||||
ViewSchema modelSchema = semanticService.getModelSchema(modelId);
|
ViewSchema modelSchema = semanticService.getViewSchema(modelId);
|
||||||
if (Objects.isNull(modelSchema)) {
|
if (Objects.isNull(modelSchema)) {
|
||||||
return new RecommendResp();
|
return new RecommendResp();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
package com.tencent.supersonic.chat.server.service.impl;
|
package com.tencent.supersonic.chat.server.service.impl;
|
||||||
|
|
||||||
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
|
|
||||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.DictWord;
|
|
||||||
import com.tencent.supersonic.headless.core.knowledge.builder.WordBuilderFactory;
|
|
||||||
import com.tencent.supersonic.chat.core.query.semantic.SemanticInterpreter;
|
import com.tencent.supersonic.chat.core.query.semantic.SemanticInterpreter;
|
||||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
|
||||||
|
import com.tencent.supersonic.headless.core.knowledge.DictWord;
|
||||||
|
import com.tencent.supersonic.headless.core.knowledge.builder.WordBuilderFactory;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -28,7 +30,6 @@ public class WordService {
|
|||||||
|
|
||||||
addWordsByType(DictWordType.DIMENSION, semanticSchema.getDimensions(), words);
|
addWordsByType(DictWordType.DIMENSION, semanticSchema.getDimensions(), words);
|
||||||
addWordsByType(DictWordType.METRIC, semanticSchema.getMetrics(), words);
|
addWordsByType(DictWordType.METRIC, semanticSchema.getMetrics(), words);
|
||||||
addWordsByType(DictWordType.VIEW, semanticSchema.getViews(), words);
|
|
||||||
addWordsByType(DictWordType.ENTITY, semanticSchema.getEntities(), words);
|
addWordsByType(DictWordType.ENTITY, semanticSchema.getEntities(), words);
|
||||||
addWordsByType(DictWordType.VALUE, semanticSchema.getDimensionValues(), words);
|
addWordsByType(DictWordType.VALUE, semanticSchema.getDimensionValues(), words);
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ public class WordService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addWordsByType(DictWordType value, List<SchemaElement> metas, List<DictWord> natures) {
|
private void addWordsByType(DictWordType value, List<SchemaElement> metas, List<DictWord> natures) {
|
||||||
|
metas = distinct(metas);
|
||||||
List<DictWord> natureList = WordBuilderFactory.get(value).getDictWords(metas);
|
List<DictWord> natureList = WordBuilderFactory.get(value).getDictWords(metas);
|
||||||
log.debug("nature type:{} , nature size:{}", value.name(), natureList.size());
|
log.debug("nature type:{} , nature size:{}", value.name(), natureList.size());
|
||||||
natures.addAll(natureList);
|
natures.addAll(natureList);
|
||||||
@@ -48,4 +50,13 @@ public class WordService {
|
|||||||
public void setPreDictWords(List<DictWord> preDictWords) {
|
public void setPreDictWords(List<DictWord> preDictWords) {
|
||||||
this.preDictWords = preDictWords;
|
this.preDictWords = preDictWords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<SchemaElement> distinct(List<SchemaElement> metas) {
|
||||||
|
return metas.stream()
|
||||||
|
.collect(Collectors.toMap(SchemaElement::getId, Function.identity(), (e1, e2) -> e1))
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ public class ModelDetail {
|
|||||||
|
|
||||||
private String tableQuery;
|
private String tableQuery;
|
||||||
|
|
||||||
private List<Identify> identifiers;
|
private List<Identify> identifiers = Lists.newArrayList();
|
||||||
|
|
||||||
private List<Dim> dimensions;
|
private List<Dim> dimensions = Lists.newArrayList();
|
||||||
|
|
||||||
private List<Measure> measures;
|
private List<Measure> measures = Lists.newArrayList();
|
||||||
|
|
||||||
private List<Field> fields;
|
private List<Field> fields = Lists.newArrayList();
|
||||||
|
|
||||||
public String getSqlQuery() {
|
public String getSqlQuery() {
|
||||||
if (StringUtils.isNotBlank(sqlQuery) && sqlQuery.endsWith(";")) {
|
if (StringUtils.isNotBlank(sqlQuery) && sqlQuery.endsWith(";")) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.tencent.supersonic.headless.api.pojo;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class Param {
|
public class Param {
|
||||||
@@ -10,7 +11,7 @@ public class Param {
|
|||||||
@NotBlank(message = "Invald parameter name")
|
@NotBlank(message = "Invald parameter name")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@NotBlank(message = "Invalid parameter value")
|
@NotNull(message = "Invalid parameter value")
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public Param() {
|
public Param() {
|
||||||
@@ -21,14 +22,4 @@ public class Param {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
final StringBuilder sb = new StringBuilder("{");
|
|
||||||
sb.append("\"name\":\"")
|
|
||||||
.append(name).append('\"');
|
|
||||||
sb.append(",\"value\":\"")
|
|
||||||
.append(value).append('\"');
|
|
||||||
sb.append('}');
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.tencent.supersonic.headless.api.pojo;
|
package com.tencent.supersonic.headless.api.pojo;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -19,6 +18,7 @@ import java.util.List;
|
|||||||
public class SchemaElement implements Serializable {
|
public class SchemaElement implements Serializable {
|
||||||
|
|
||||||
private Long view;
|
private Long view;
|
||||||
|
private Long model;
|
||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
private String bizName;
|
private String bizName;
|
||||||
@@ -52,7 +52,4 @@ public class SchemaElement implements Serializable {
|
|||||||
return Objects.hashCode(view, id, name, bizName, type);
|
return Objects.hashCode(view, id, name, bizName, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getModelNames() {
|
|
||||||
return Lists.newArrayList(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ public class MetricResp extends SchemaItem {
|
|||||||
|
|
||||||
private Long domainId;
|
private Long domainId;
|
||||||
|
|
||||||
|
private String modelBizName;
|
||||||
|
|
||||||
private String modelName;
|
private String modelName;
|
||||||
|
|
||||||
//ATOMIC DERIVED
|
//ATOMIC DERIVED
|
||||||
|
|||||||
@@ -6,8 +6,15 @@ import com.hankcs.hanlp.corpus.tag.Nature;
|
|||||||
import com.hankcs.hanlp.dictionary.CoreDictionary;
|
import com.hankcs.hanlp.dictionary.CoreDictionary;
|
||||||
import com.hankcs.hanlp.seg.common.Term;
|
import com.hankcs.hanlp.seg.common.Term;
|
||||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.request.DimensionValueReq;
|
||||||
|
import com.tencent.supersonic.headless.core.knowledge.helper.NatureHelper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -17,11 +24,6 @@ import java.util.TreeMap;
|
|||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.tencent.supersonic.headless.api.pojo.request.DimensionValueReq;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SearchService {
|
public class SearchService {
|
||||||
|
|
||||||
@@ -39,14 +41,14 @@ public class SearchService {
|
|||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static List<HanlpMapResult> prefixSearch(String key, int limit, Set<Long> detectModelIds) {
|
public static List<HanlpMapResult> prefixSearch(String key, int limit, Map<Long, List<Long>> modelIdToViewIds) {
|
||||||
return prefixSearch(key, limit, trie, detectModelIds);
|
return prefixSearch(key, limit, trie, modelIdToViewIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<HanlpMapResult> prefixSearch(String key, int limit, BinTrie<List<String>> binTrie,
|
public static List<HanlpMapResult> prefixSearch(String key, int limit, BinTrie<List<String>> binTrie,
|
||||||
Set<Long> detectModelIds) {
|
Map<Long, List<Long>> modelIdToViewIds) {
|
||||||
Set<Map.Entry<String, List<String>>> result = prefixSearchLimit(key, limit, binTrie, detectModelIds);
|
Set<Map.Entry<String, List<String>>> result = prefixSearchLimit(key, limit, binTrie, modelIdToViewIds.keySet());
|
||||||
return result.stream().map(
|
List<HanlpMapResult> hanlpMapResults = result.stream().map(
|
||||||
entry -> {
|
entry -> {
|
||||||
String name = entry.getKey().replace("#", " ");
|
String name = entry.getKey().replace("#", " ");
|
||||||
return new HanlpMapResult(name, entry.getValue(), key);
|
return new HanlpMapResult(name, entry.getValue(), key);
|
||||||
@@ -54,6 +56,13 @@ public class SearchService {
|
|||||||
).sorted((a, b) -> -(b.getName().length() - a.getName().length()))
|
).sorted((a, b) -> -(b.getName().length() - a.getName().length()))
|
||||||
.limit(SEARCH_SIZE)
|
.limit(SEARCH_SIZE)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
for (HanlpMapResult hanlpMapResult : hanlpMapResults) {
|
||||||
|
List<String> natures = hanlpMapResult.getNatures().stream()
|
||||||
|
.map(nature -> NatureHelper.changeModel2View(nature, modelIdToViewIds))
|
||||||
|
.flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
|
hanlpMapResult.setNatures(natures);
|
||||||
|
}
|
||||||
|
return hanlpMapResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ public class DimensionWordBuilder extends BaseWordBuilder {
|
|||||||
private DictWord getOnwWordNature(String word, SchemaElement schemaElement, boolean isSuffix) {
|
private DictWord getOnwWordNature(String word, SchemaElement schemaElement, boolean isSuffix) {
|
||||||
DictWord dictWord = new DictWord();
|
DictWord dictWord = new DictWord();
|
||||||
dictWord.setWord(word);
|
dictWord.setWord(word);
|
||||||
Long viewId = schemaElement.getView();
|
Long modelId = schemaElement.getModel();
|
||||||
String nature = DictWordType.NATURE_SPILT + viewId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
String nature = DictWordType.NATURE_SPILT + modelId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
||||||
+ DictWordType.DIMENSION.getType();
|
+ DictWordType.DIMENSION.getType();
|
||||||
if (isSuffix) {
|
if (isSuffix) {
|
||||||
nature = DictWordType.NATURE_SPILT + viewId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
nature = DictWordType.NATURE_SPILT + modelId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
||||||
+ DictWordType.SUFFIX.getType() + DictWordType.DIMENSION.getType();
|
+ DictWordType.SUFFIX.getType() + DictWordType.DIMENSION.getType();
|
||||||
}
|
}
|
||||||
dictWord.setNatureWithFrequency(String.format("%s " + DEFAULT_FREQUENCY, nature));
|
dictWord.setNatureWithFrequency(String.format("%s " + DEFAULT_FREQUENCY, nature));
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ public class EntityWordBuilder extends BaseWordBuilder {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Long view = schemaElement.getView();
|
Long modelId = schemaElement.getModel();
|
||||||
String nature = DictWordType.NATURE_SPILT + view + DictWordType.NATURE_SPILT + schemaElement.getId()
|
String nature = DictWordType.NATURE_SPILT + modelId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
||||||
+ DictWordType.ENTITY.getType();
|
+ DictWordType.ENTITY.getType();
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(schemaElement.getAlias())) {
|
if (!CollectionUtils.isEmpty(schemaElement.getAlias())) {
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ public class MetricWordBuilder extends BaseWordBuilder {
|
|||||||
private DictWord getOnwWordNature(String word, SchemaElement schemaElement, boolean isSuffix) {
|
private DictWord getOnwWordNature(String word, SchemaElement schemaElement, boolean isSuffix) {
|
||||||
DictWord dictWord = new DictWord();
|
DictWord dictWord = new DictWord();
|
||||||
dictWord.setWord(word);
|
dictWord.setWord(word);
|
||||||
Long viewId = schemaElement.getView();
|
Long modelId = schemaElement.getModel();
|
||||||
String nature = DictWordType.NATURE_SPILT + viewId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
String nature = DictWordType.NATURE_SPILT + modelId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
||||||
+ DictWordType.METRIC.getType();
|
+ DictWordType.METRIC.getType();
|
||||||
if (isSuffix) {
|
if (isSuffix) {
|
||||||
nature = DictWordType.NATURE_SPILT + viewId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
nature = DictWordType.NATURE_SPILT + modelId + DictWordType.NATURE_SPILT + schemaElement.getId()
|
||||||
+ DictWordType.SUFFIX.getType() + DictWordType.METRIC.getType();
|
+ DictWordType.SUFFIX.getType() + DictWordType.METRIC.getType();
|
||||||
}
|
}
|
||||||
dictWord.setNatureWithFrequency(String.format("%s " + DEFAULT_FREQUENCY, nature));
|
dictWord.setNatureWithFrequency(String.format("%s " + DEFAULT_FREQUENCY, nature));
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ public class ValueWordBuilder extends BaseWordBuilder {
|
|||||||
|
|
||||||
schemaElement.getAlias().stream().forEach(value -> {
|
schemaElement.getAlias().stream().forEach(value -> {
|
||||||
DictWord dictWord = new DictWord();
|
DictWord dictWord = new DictWord();
|
||||||
Long viewId = schemaElement.getView();
|
Long modelId = schemaElement.getModel();
|
||||||
String nature = DictWordType.NATURE_SPILT + viewId + DictWordType.NATURE_SPILT + schemaElement.getId();
|
String nature = DictWordType.NATURE_SPILT + modelId + DictWordType.NATURE_SPILT + schemaElement.getId();
|
||||||
dictWord.setNatureWithFrequency(String.format("%s " + DEFAULT_FREQUENCY, nature));
|
dictWord.setNatureWithFrequency(String.format("%s " + DEFAULT_FREQUENCY, nature));
|
||||||
dictWord.setWord(value);
|
dictWord.setWord(value);
|
||||||
result.add(dictWord);
|
result.add(dictWord);
|
||||||
|
|||||||
@@ -1,34 +1,36 @@
|
|||||||
package com.tencent.supersonic.headless.core.knowledge.helper;
|
package com.tencent.supersonic.headless.core.knowledge.helper;
|
||||||
|
|
||||||
import static com.hankcs.hanlp.HanLP.Config.CustomDictionaryPath;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import com.hankcs.hanlp.HanLP;
|
import com.hankcs.hanlp.HanLP;
|
||||||
import com.hankcs.hanlp.corpus.tag.Nature;
|
import com.hankcs.hanlp.corpus.tag.Nature;
|
||||||
import com.hankcs.hanlp.dictionary.CoreDictionary;
|
import com.hankcs.hanlp.dictionary.CoreDictionary;
|
||||||
import com.hankcs.hanlp.dictionary.DynamicCustomDictionary;
|
import com.hankcs.hanlp.dictionary.DynamicCustomDictionary;
|
||||||
import com.hankcs.hanlp.seg.Segment;
|
import com.hankcs.hanlp.seg.Segment;
|
||||||
|
import com.hankcs.hanlp.seg.common.Term;
|
||||||
|
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.S2Term;
|
import com.tencent.supersonic.headless.api.pojo.response.S2Term;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.DictWord;
|
import com.tencent.supersonic.headless.core.knowledge.DictWord;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.HadoopFileIOAdapter;
|
import com.tencent.supersonic.headless.core.knowledge.HadoopFileIOAdapter;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.MapResult;
|
import com.tencent.supersonic.headless.core.knowledge.MapResult;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.MultiCustomDictionary;
|
import com.tencent.supersonic.headless.core.knowledge.MultiCustomDictionary;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.SearchService;
|
import com.tencent.supersonic.headless.core.knowledge.SearchService;
|
||||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.hankcs.hanlp.seg.common.Term;
|
import static com.hankcs.hanlp.HanLP.Config.CustomDictionaryPath;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.util.ResourceUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HanLP helper
|
* HanLP helper
|
||||||
@@ -212,18 +214,25 @@ public class HanlpHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<com.tencent.supersonic.headless.api.pojo.response.S2Term> getTerms(String text) {
|
public static List<S2Term> getTerms(String text, Map<Long, List<Long>> modelIdToViewIds) {
|
||||||
return getSegment().seg(text.toLowerCase()).stream()
|
return getSegment().seg(text.toLowerCase()).stream()
|
||||||
.filter(term -> term.getNature().startsWith(DictWordType.NATURE_SPILT))
|
.filter(term -> term.getNature().startsWith(DictWordType.NATURE_SPILT))
|
||||||
.map(term -> transform2ApiTerm(term))
|
.map(term -> transform2ApiTerm(term, modelIdToViewIds))
|
||||||
|
.flatMap(Collection::stream)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S2Term transform2ApiTerm(Term term) {
|
public static List<S2Term> transform2ApiTerm(Term term, Map<Long, List<Long>> modelIdToViewIds) {
|
||||||
S2Term knowledgeTerm = new S2Term();
|
List<S2Term> s2Terms = Lists.newArrayList();
|
||||||
BeanUtils.copyProperties(term, knowledgeTerm);
|
List<String> natures = NatureHelper.changeModel2View(String.valueOf(term.getNature()), modelIdToViewIds);
|
||||||
knowledgeTerm.setFrequency(term.getFrequency());
|
for (String nature : natures) {
|
||||||
return knowledgeTerm;
|
S2Term s2Term = new S2Term();
|
||||||
|
BeanUtils.copyProperties(term, s2Term);
|
||||||
|
s2Term.setNature(Nature.create(nature));
|
||||||
|
s2Term.setFrequency(term.getFrequency());
|
||||||
|
s2Terms.add(s2Term);
|
||||||
|
}
|
||||||
|
return s2Terms;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package com.tencent.supersonic.headless.core.knowledge.helper;
|
package com.tencent.supersonic.headless.core.knowledge.helper;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.hankcs.hanlp.corpus.tag.Nature;
|
import com.hankcs.hanlp.corpus.tag.Nature;
|
||||||
|
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SchemaElementType;
|
import com.tencent.supersonic.headless.api.pojo.SchemaElementType;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.S2Term;
|
import com.tencent.supersonic.headless.api.pojo.response.S2Term;
|
||||||
import com.tencent.supersonic.headless.core.knowledge.ViewInfoStat;
|
import com.tencent.supersonic.headless.core.knowledge.ViewInfoStat;
|
||||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -81,6 +83,43 @@ public class NatureHelper {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Long getModelId(String nature) {
|
||||||
|
try {
|
||||||
|
String[] split = nature.split(DictWordType.NATURE_SPILT);
|
||||||
|
if (split.length <= 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Long.valueOf(split[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.error("", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Nature changeModel2View(String nature, Long viewId) {
|
||||||
|
try {
|
||||||
|
String[] split = nature.split(DictWordType.NATURE_SPILT);
|
||||||
|
if (split.length <= 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
split[1] = String.valueOf(viewId);
|
||||||
|
return Nature.create(StringUtils.join(split, DictWordType.NATURE_SPILT));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.error("", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> changeModel2View(String nature, Map<Long, List<Long>> modelIdToViewIds) {
|
||||||
|
Long modelId = getModelId(nature);
|
||||||
|
List<Long> viewIds = modelIdToViewIds.get(modelId);
|
||||||
|
if (CollectionUtils.isEmpty(viewIds)) {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
return viewIds.stream().map(viewId -> String.valueOf(changeModel2View(nature, viewId)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isDimensionValueViewId(String nature) {
|
public static boolean isDimensionValueViewId(String nature) {
|
||||||
if (StringUtils.isEmpty(nature)) {
|
if (StringUtils.isEmpty(nature)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ import com.tencent.supersonic.headless.api.pojo.response.MetricResp;
|
|||||||
import com.tencent.supersonic.headless.api.pojo.response.MetricSchemaResp;
|
import com.tencent.supersonic.headless.api.pojo.response.MetricSchemaResp;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp;
|
import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp;
|
||||||
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
|
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
|
||||||
|
import com.tencent.supersonic.headless.server.service.MetricService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -28,6 +30,9 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class MetricDrillDownChecker {
|
public class MetricDrillDownChecker {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MetricService metricService;
|
||||||
|
|
||||||
@Around("execution(* com.tencent.supersonic.headless.core.parser.QueryParser.parse(..))")
|
@Around("execution(* com.tencent.supersonic.headless.core.parser.QueryParser.parse(..))")
|
||||||
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
Object[] objects = joinPoint.getArgs();
|
Object[] objects = joinPoint.getArgs();
|
||||||
@@ -52,7 +57,7 @@ public class MetricDrillDownChecker {
|
|||||||
List<DimensionResp> necessaryDimensions = getNecessaryDimensions(metric, semanticSchemaResp);
|
List<DimensionResp> necessaryDimensions = getNecessaryDimensions(metric, semanticSchemaResp);
|
||||||
List<DimensionResp> dimensionsMissing = getNecessaryDimensionMissing(necessaryDimensions, dimensionFields);
|
List<DimensionResp> dimensionsMissing = getNecessaryDimensionMissing(necessaryDimensions, dimensionFields);
|
||||||
if (!CollectionUtils.isEmpty(dimensionsMissing)) {
|
if (!CollectionUtils.isEmpty(dimensionsMissing)) {
|
||||||
String errMsg = String.format("指标:%s 缺失必要维度:%s", metric.getName(),
|
String errMsg = String.format("指标:%s 缺失必要下钻维度:%s", metric.getName(),
|
||||||
dimensionsMissing.stream().map(DimensionResp::getName).collect(Collectors.toList()));
|
dimensionsMissing.stream().map(DimensionResp::getName).collect(Collectors.toList()));
|
||||||
throw new InvalidArgumentException(errMsg);
|
throw new InvalidArgumentException(errMsg);
|
||||||
}
|
}
|
||||||
@@ -92,8 +97,9 @@ public class MetricDrillDownChecker {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
List<String> relateDimensions = metricResps.stream()
|
List<String> relateDimensions = metricResps.stream()
|
||||||
.filter(metric -> !CollectionUtils.isEmpty(metric.getDrillDownDimensions()))
|
.map(this::getDrillDownDimensions)
|
||||||
.map(metric -> metric.getDrillDownDimensions().stream()
|
.filter(drillDownDimensions -> !CollectionUtils.isEmpty(drillDownDimensions))
|
||||||
|
.map(drillDownDimensions -> drillDownDimensions.stream()
|
||||||
.map(DrillDownDimension::getDimensionId).collect(Collectors.toList()))
|
.map(DrillDownDimension::getDimensionId).collect(Collectors.toList()))
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.map(id -> convertDimensionIdToBizName(id, semanticSchemaResp))
|
.map(id -> convertDimensionIdToBizName(id, semanticSchemaResp))
|
||||||
@@ -111,7 +117,7 @@ public class MetricDrillDownChecker {
|
|||||||
if (metric == null) {
|
if (metric == null) {
|
||||||
return Lists.newArrayList();
|
return Lists.newArrayList();
|
||||||
}
|
}
|
||||||
List<DrillDownDimension> drillDownDimensions = metric.getDrillDownDimensions();
|
List<DrillDownDimension> drillDownDimensions = getDrillDownDimensions(metric);
|
||||||
if (CollectionUtils.isEmpty(drillDownDimensions)) {
|
if (CollectionUtils.isEmpty(drillDownDimensions)) {
|
||||||
return Lists.newArrayList();
|
return Lists.newArrayList();
|
||||||
}
|
}
|
||||||
@@ -147,4 +153,8 @@ public class MetricDrillDownChecker {
|
|||||||
return dimension.getBizName();
|
return dimension.getBizName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<DrillDownDimension> getDrillDownDimensions(MetricResp metricResp) {
|
||||||
|
return metricService.getDrillDownDimension(metricResp.getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class ModelYamlManager {
|
public class ModelYamlManager {
|
||||||
|
|
||||||
public static DataModelYamlTpl convert2YamlObj(ModelResp modelResp, DatabaseResp databaseResp) {
|
public static synchronized DataModelYamlTpl convert2YamlObj(ModelResp modelResp, DatabaseResp databaseResp) {
|
||||||
ModelDetail modelDetail = modelResp.getModelDetail();
|
ModelDetail modelDetail = modelResp.getModelDetail();
|
||||||
DbAdaptor engineAdaptor = DbAdaptorFactory.getEngineAdaptor(databaseResp.getType());
|
DbAdaptor engineAdaptor = DbAdaptorFactory.getEngineAdaptor(databaseResp.getType());
|
||||||
SysTimeDimensionBuilder.addSysTimeDimension(modelDetail.getDimensions(), engineAdaptor);
|
SysTimeDimensionBuilder.addSysTimeDimension(modelDetail.getDimensions(), engineAdaptor);
|
||||||
|
|||||||
@@ -109,8 +109,9 @@ public class DownloadServiceImpl implements DownloadService {
|
|||||||
metaFilter.setIds(metricIds);
|
metaFilter.setIds(metricIds);
|
||||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||||
Map<String, List<MetricResp>> metricMap = getMetricMap(metricResps);
|
Map<String, List<MetricResp>> metricMap = getMetricMap(metricResps);
|
||||||
List<Long> dimensionIds = metricResps.stream().map(MetricResp::getRelateDimension)
|
List<Long> dimensionIds = metricResps.stream()
|
||||||
.map(RelateDimension::getDrillDownDimensions).flatMap(Collection::stream)
|
.map(metricResp -> metricService.getDrillDownDimension(metricResp.getId()))
|
||||||
|
.flatMap(Collection::stream)
|
||||||
.map(DrillDownDimension::getDimensionId).collect(Collectors.toList());
|
.map(DrillDownDimension::getDimensionId).collect(Collectors.toList());
|
||||||
metaFilter.setIds(dimensionIds);
|
metaFilter.setIds(dimensionIds);
|
||||||
Map<Long, DimensionResp> dimensionRespMap = dimensionService.getDimensions(metaFilter)
|
Map<Long, DimensionResp> dimensionRespMap = dimensionService.getDimensions(metaFilter)
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import com.tencent.supersonic.headless.core.knowledge.SearchService;
|
|||||||
import com.tencent.supersonic.headless.core.knowledge.helper.HanlpHelper;
|
import com.tencent.supersonic.headless.core.knowledge.helper.HanlpHelper;
|
||||||
import com.tencent.supersonic.headless.server.service.KnowledgeService;
|
import com.tencent.supersonic.headless.server.service.KnowledgeService;
|
||||||
import com.tencent.supersonic.headless.server.service.ViewService;
|
import com.tencent.supersonic.headless.server.service.ViewService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -68,17 +69,19 @@ public class KnowledgeServiceImpl implements KnowledgeService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<S2Term> getTerms(String text) {
|
public List<S2Term> getTerms(String text) {
|
||||||
return HanlpHelper.getTerms(text);
|
Map<Long, List<Long>> modelIdToViewIds = viewService.getModelIdToViewIds(new ArrayList<>());
|
||||||
|
return HanlpHelper.getTerms(text, modelIdToViewIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HanlpMapResult> prefixSearch(String key, int limit, Set<Long> viewIds) {
|
public List<HanlpMapResult> prefixSearch(String key, int limit, Set<Long> viewIds) {
|
||||||
Map<Long, List<Long>> modelIdToViewIds = viewService.getModelIdToViewIds(new ArrayList<>(viewIds));
|
Map<Long, List<Long>> modelIdToViewIds = viewService.getModelIdToViewIds(new ArrayList<>(viewIds));
|
||||||
return prefixSearchByModel(key, limit, modelIdToViewIds.keySet());
|
return prefixSearchByModel(key, limit, modelIdToViewIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<HanlpMapResult> prefixSearchByModel(String key, int limit, Set<Long> models) {
|
public List<HanlpMapResult> prefixSearchByModel(String key, int limit,
|
||||||
return SearchService.prefixSearch(key, limit, models);
|
Map<Long, List<Long>> modelIdToViewIds) {
|
||||||
|
return SearchService.prefixSearch(key, limit, modelIdToViewIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.alibaba.fastjson.TypeReference;
|
|||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||||
import com.tencent.supersonic.common.pojo.Constants;
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
import com.tencent.supersonic.common.pojo.DataEvent;
|
import com.tencent.supersonic.common.pojo.DataEvent;
|
||||||
@@ -16,6 +17,7 @@ import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
|||||||
import com.tencent.supersonic.common.util.BeanMapper;
|
import com.tencent.supersonic.common.util.BeanMapper;
|
||||||
import com.tencent.supersonic.common.util.ChatGptHelper;
|
import com.tencent.supersonic.common.util.ChatGptHelper;
|
||||||
import com.tencent.supersonic.headless.api.pojo.DrillDownDimension;
|
import com.tencent.supersonic.headless.api.pojo.DrillDownDimension;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.MeasureParam;
|
||||||
import com.tencent.supersonic.headless.api.pojo.MetricParam;
|
import com.tencent.supersonic.headless.api.pojo.MetricParam;
|
||||||
import com.tencent.supersonic.headless.api.pojo.MetricQueryDefaultConfig;
|
import com.tencent.supersonic.headless.api.pojo.MetricQueryDefaultConfig;
|
||||||
import com.tencent.supersonic.headless.api.pojo.enums.MetricDefineType;
|
import com.tencent.supersonic.headless.api.pojo.enums.MetricDefineType;
|
||||||
@@ -40,6 +42,12 @@ import com.tencent.supersonic.headless.server.service.ModelService;
|
|||||||
import com.tencent.supersonic.headless.server.service.ViewService;
|
import com.tencent.supersonic.headless.server.service.ViewService;
|
||||||
import com.tencent.supersonic.headless.server.utils.MetricCheckUtils;
|
import com.tencent.supersonic.headless.server.utils.MetricCheckUtils;
|
||||||
import com.tencent.supersonic.headless.server.utils.MetricConverter;
|
import com.tencent.supersonic.headless.server.utils.MetricConverter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -48,11 +56,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -228,28 +231,44 @@ public class MetricServiceImpl implements MetricService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<MetricResp> filterByField(List<MetricResp> metricResps, List<String> fields) {
|
private List<MetricResp> filterByField(List<MetricResp> metricResps, List<String> fields) {
|
||||||
List<MetricResp> metricRespFiltered = Lists.newArrayList();
|
Set<MetricResp> metricRespFiltered = Sets.newHashSet();
|
||||||
for (MetricResp metricResp : metricResps) {
|
for (MetricResp metricResp : metricResps) {
|
||||||
for (String field : fields) {
|
filterByField(metricResps, metricResp, fields, metricRespFiltered);
|
||||||
if (MetricDefineType.METRIC.equals(metricResp.getMetricDefineType())) {
|
}
|
||||||
List<Long> ids = metricResp.getMetricDefineByMetricParams().getMetrics()
|
return new ArrayList<>(metricRespFiltered);
|
||||||
.stream().map(MetricParam::getId).collect(Collectors.toList());
|
}
|
||||||
List<MetricResp> metricById = metricResps.stream()
|
|
||||||
.filter(metric -> ids.contains(metric.getId()))
|
private boolean filterByField(List<MetricResp> metricResps, MetricResp metricResp,
|
||||||
.collect(Collectors.toList());
|
List<String> fields, Set<MetricResp> metricRespFiltered) {
|
||||||
for (MetricResp metric : metricById) {
|
if (MetricDefineType.METRIC.equals(metricResp.getMetricDefineType())) {
|
||||||
if (metric.getExpr().contains(field)) {
|
List<Long> ids = metricResp.getMetricDefineByMetricParams().getMetrics()
|
||||||
metricRespFiltered.add(metricResp);
|
.stream().map(MetricParam::getId).collect(Collectors.toList());
|
||||||
}
|
List<MetricResp> metricById = metricResps.stream()
|
||||||
}
|
.filter(metric -> ids.contains(metric.getId()))
|
||||||
} else {
|
.collect(Collectors.toList());
|
||||||
if (metricResp.getExpr().contains(field)) {
|
for (MetricResp metric : metricById) {
|
||||||
metricRespFiltered.add(metricResp);
|
if (filterByField(metricResps, metric, fields, metricRespFiltered)) {
|
||||||
}
|
metricRespFiltered.add(metricResp);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (MetricDefineType.FIELD.equals(metricResp.getMetricDefineType())) {
|
||||||
|
if (fields.stream().anyMatch(field -> metricResp.getExpr().contains(field))) {
|
||||||
|
metricRespFiltered.add(metricResp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (MetricDefineType.MEASURE.equals(metricResp.getMetricDefineType())) {
|
||||||
|
List<MeasureParam> measures = metricResp.getMetricDefineByMeasureParams().getMeasures();
|
||||||
|
List<String> fieldNameDepended = measures.stream().map(MeasureParam::getBizName)
|
||||||
|
//measure bizName = model bizName_fieldName
|
||||||
|
.map(name -> name.replaceFirst(metricResp.getModelBizName() + "_", ""))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (fields.stream().anyMatch(fieldNameDepended::contains)) {
|
||||||
|
metricRespFiltered.add(metricResp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return metricRespFiltered;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -64,6 +64,13 @@ public class SchemaServiceImpl implements SchemaService {
|
|||||||
|
|
||||||
protected final Cache<String, List<ItemUseResp>> itemUseCache =
|
protected final Cache<String, List<ItemUseResp>> itemUseCache =
|
||||||
CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.DAYS).build();
|
CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.DAYS).build();
|
||||||
|
|
||||||
|
protected final Cache<ViewFilterReq, List<ViewSchemaResp>> viewSchemaCache =
|
||||||
|
CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build();
|
||||||
|
|
||||||
|
protected final Cache<SchemaFilterReq, SemanticSchemaResp> semanticSchemaCache =
|
||||||
|
CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build();
|
||||||
|
|
||||||
private final StatUtils statUtils;
|
private final StatUtils statUtils;
|
||||||
private final ModelService modelService;
|
private final ModelService modelService;
|
||||||
private final DimensionService dimensionService;
|
private final DimensionService dimensionService;
|
||||||
@@ -91,6 +98,22 @@ public class SchemaServiceImpl implements SchemaService {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public List<ViewSchemaResp> fetchViewSchema(ViewFilterReq filter) {
|
public List<ViewSchemaResp> fetchViewSchema(ViewFilterReq filter) {
|
||||||
|
List<ViewSchemaResp> viewList = viewSchemaCache.getIfPresent(filter);
|
||||||
|
if (CollectionUtils.isEmpty(viewList)) {
|
||||||
|
viewList = buildViewSchema(filter);
|
||||||
|
viewSchemaCache.put(filter, viewList);
|
||||||
|
}
|
||||||
|
return viewList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViewSchemaResp fetchViewSchema(Long viewId) {
|
||||||
|
if (viewId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return fetchViewSchema(new ViewFilterReq(viewId)).stream().findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ViewSchemaResp> buildViewSchema(ViewFilterReq filter) {
|
||||||
List<ViewSchemaResp> viewSchemaResps = new ArrayList<>();
|
List<ViewSchemaResp> viewSchemaResps = new ArrayList<>();
|
||||||
List<Long> viewIds = filter.getViewIds();
|
List<Long> viewIds = filter.getViewIds();
|
||||||
MetaFilter metaFilter = new MetaFilter();
|
MetaFilter metaFilter = new MetaFilter();
|
||||||
@@ -127,13 +150,6 @@ public class SchemaServiceImpl implements SchemaService {
|
|||||||
return viewSchemaResps;
|
return viewSchemaResps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewSchemaResp fetchViewSchema(Long viewId) {
|
|
||||||
if (viewId == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return fetchViewSchema(new ViewFilterReq(viewId)).stream().findFirst().orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ModelSchemaResp> fetchModelSchemaResps(List<Long> modelIds) {
|
public List<ModelSchemaResp> fetchModelSchemaResps(List<Long> modelIds) {
|
||||||
List<ModelSchemaResp> modelSchemaResps = Lists.newArrayList();
|
List<ModelSchemaResp> modelSchemaResps = Lists.newArrayList();
|
||||||
if (CollectionUtils.isEmpty(modelIds)) {
|
if (CollectionUtils.isEmpty(modelIds)) {
|
||||||
@@ -258,8 +274,7 @@ public class SchemaServiceImpl implements SchemaService {
|
|||||||
return viewService.getViewList(metaFilter);
|
return viewService.getViewList(metaFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public SemanticSchemaResp buildSemanticSchema(SchemaFilterReq schemaFilterReq) {
|
||||||
public SemanticSchemaResp fetchSemanticSchema(SchemaFilterReq schemaFilterReq) {
|
|
||||||
SemanticSchemaResp semanticSchemaResp = new SemanticSchemaResp();
|
SemanticSchemaResp semanticSchemaResp = new SemanticSchemaResp();
|
||||||
semanticSchemaResp.setViewId(schemaFilterReq.getViewId());
|
semanticSchemaResp.setViewId(schemaFilterReq.getViewId());
|
||||||
semanticSchemaResp.setModelIds(schemaFilterReq.getModelIds());
|
semanticSchemaResp.setModelIds(schemaFilterReq.getModelIds());
|
||||||
@@ -294,6 +309,16 @@ public class SchemaServiceImpl implements SchemaService {
|
|||||||
return semanticSchemaResp;
|
return semanticSchemaResp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SemanticSchemaResp fetchSemanticSchema(SchemaFilterReq schemaFilterReq) {
|
||||||
|
SemanticSchemaResp semanticSchemaResp = semanticSchemaCache.getIfPresent(schemaFilterReq);
|
||||||
|
if (semanticSchemaResp == null) {
|
||||||
|
semanticSchemaResp = buildSemanticSchema(schemaFilterReq);
|
||||||
|
semanticSchemaCache.put(schemaFilterReq, semanticSchemaResp);
|
||||||
|
}
|
||||||
|
return semanticSchemaResp;
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public List<ItemUseResp> getStatInfo(ItemUseReq itemUseReq) {
|
public List<ItemUseResp> getStatInfo(ItemUseReq itemUseReq) {
|
||||||
|
|||||||
@@ -10,17 +10,29 @@ import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
|||||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||||
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
||||||
|
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
|
||||||
import com.tencent.supersonic.common.util.BeanMapper;
|
import com.tencent.supersonic.common.util.BeanMapper;
|
||||||
import com.tencent.supersonic.headless.api.pojo.QueryConfig;
|
import com.tencent.supersonic.headless.api.pojo.QueryConfig;
|
||||||
import com.tencent.supersonic.headless.api.pojo.ViewDetail;
|
import com.tencent.supersonic.headless.api.pojo.ViewDetail;
|
||||||
import com.tencent.supersonic.headless.api.pojo.request.ViewReq;
|
import com.tencent.supersonic.headless.api.pojo.request.ViewReq;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.response.DimensionResp;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.DomainResp;
|
import com.tencent.supersonic.headless.api.pojo.response.DomainResp;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.response.MetricResp;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.ViewResp;
|
import com.tencent.supersonic.headless.api.pojo.response.ViewResp;
|
||||||
import com.tencent.supersonic.headless.server.persistence.dataobject.ViewDO;
|
import com.tencent.supersonic.headless.server.persistence.dataobject.ViewDO;
|
||||||
import com.tencent.supersonic.headless.server.persistence.mapper.ViewDOMapper;
|
import com.tencent.supersonic.headless.server.persistence.mapper.ViewDOMapper;
|
||||||
import com.tencent.supersonic.headless.server.pojo.MetaFilter;
|
import com.tencent.supersonic.headless.server.pojo.MetaFilter;
|
||||||
|
import com.tencent.supersonic.headless.server.service.DimensionService;
|
||||||
import com.tencent.supersonic.headless.server.service.DomainService;
|
import com.tencent.supersonic.headless.server.service.DomainService;
|
||||||
|
import com.tencent.supersonic.headless.server.service.MetricService;
|
||||||
import com.tencent.supersonic.headless.server.service.ViewService;
|
import com.tencent.supersonic.headless.server.service.ViewService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -29,12 +41,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ViewServiceImpl
|
public class ViewServiceImpl
|
||||||
@@ -46,21 +54,33 @@ public class ViewServiceImpl
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DomainService domainService;
|
private DomainService domainService;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Autowired
|
||||||
|
private DimensionService dimensionService;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Autowired
|
||||||
|
private MetricService metricService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewResp save(ViewReq viewReq, User user) {
|
public ViewResp save(ViewReq viewReq, User user) {
|
||||||
viewReq.createdBy(user.getName());
|
viewReq.createdBy(user.getName());
|
||||||
ViewDO viewDO = convert(viewReq);
|
ViewDO viewDO = convert(viewReq);
|
||||||
viewDO.setStatus(StatusEnum.ONLINE.getCode());
|
viewDO.setStatus(StatusEnum.ONLINE.getCode());
|
||||||
|
ViewResp viewResp = convert(viewDO);
|
||||||
|
conflictCheck(viewResp);
|
||||||
save(viewDO);
|
save(viewDO);
|
||||||
return convert(viewDO);
|
return viewResp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewResp update(ViewReq viewReq, User user) {
|
public ViewResp update(ViewReq viewReq, User user) {
|
||||||
viewReq.updatedBy(user.getName());
|
viewReq.updatedBy(user.getName());
|
||||||
ViewDO viewDO = convert(viewReq);
|
ViewDO viewDO = convert(viewReq);
|
||||||
|
ViewResp viewResp = convert(viewDO);
|
||||||
|
conflictCheck(viewResp);
|
||||||
updateById(viewDO);
|
updateById(viewDO);
|
||||||
return convert(viewDO);
|
return viewResp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,6 +98,9 @@ public class ViewServiceImpl
|
|||||||
if (!CollectionUtils.isEmpty(metaFilter.getIds())) {
|
if (!CollectionUtils.isEmpty(metaFilter.getIds())) {
|
||||||
wrapper.lambda().in(ViewDO::getId, metaFilter.getIds());
|
wrapper.lambda().in(ViewDO::getId, metaFilter.getIds());
|
||||||
}
|
}
|
||||||
|
if (metaFilter.getStatus() != null) {
|
||||||
|
wrapper.lambda().eq(ViewDO::getStatus, metaFilter.getStatus());
|
||||||
|
}
|
||||||
wrapper.lambda().ne(ViewDO::getStatus, StatusEnum.DELETED.getCode());
|
wrapper.lambda().ne(ViewDO::getStatus, StatusEnum.DELETED.getCode());
|
||||||
return list(wrapper).stream().map(this::convert).collect(Collectors.toList());
|
return list(wrapper).stream().map(this::convert).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
@@ -175,4 +198,43 @@ public class ViewServiceImpl
|
|||||||
viewResp -> viewResp.getAllModels().stream().map(modelId -> Pair.of(modelId, viewResp.getId())))
|
viewResp -> viewResp.getAllModels().stream().map(modelId -> Pair.of(modelId, viewResp.getId())))
|
||||||
.collect(Collectors.groupingBy(Pair::getLeft, Collectors.mapping(Pair::getRight, Collectors.toList())));
|
.collect(Collectors.groupingBy(Pair::getLeft, Collectors.mapping(Pair::getRight, Collectors.toList())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void conflictCheck(ViewResp viewResp) {
|
||||||
|
List<Long> allDimensionIds = viewResp.getAllDimensions();
|
||||||
|
List<Long> allMetricIds = viewResp.getAllMetrics();
|
||||||
|
MetaFilter metaFilter = new MetaFilter();
|
||||||
|
metaFilter.setIds(allDimensionIds);
|
||||||
|
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||||
|
metaFilter.setIds(allMetricIds);
|
||||||
|
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||||
|
|
||||||
|
List<String> duplicateDimensionNames = findDuplicates(dimensionResps, DimensionResp::getName);
|
||||||
|
List<String> duplicateDimensionBizNames = findDuplicates(dimensionResps, DimensionResp::getBizName);
|
||||||
|
|
||||||
|
List<String> duplicateMetricNames = findDuplicates(metricResps, MetricResp::getName);
|
||||||
|
List<String> duplicateMetricBizNames = findDuplicates(metricResps, MetricResp::getBizName);
|
||||||
|
if (!duplicateDimensionNames.isEmpty()) {
|
||||||
|
throw new InvalidArgumentException("存在相同的维度名: " + duplicateDimensionNames);
|
||||||
|
}
|
||||||
|
if (!duplicateDimensionBizNames.isEmpty()) {
|
||||||
|
throw new InvalidArgumentException("存在相同的维度英文名: " + duplicateDimensionBizNames);
|
||||||
|
}
|
||||||
|
if (!duplicateMetricNames.isEmpty()) {
|
||||||
|
throw new InvalidArgumentException("存在相同的指标名: " + duplicateMetricNames);
|
||||||
|
}
|
||||||
|
if (!duplicateMetricBizNames.isEmpty()) {
|
||||||
|
throw new InvalidArgumentException("存在相同的指标英文名: " + duplicateMetricBizNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T, R> List<String> findDuplicates(List<T> list, Function<T, R> keyExtractor) {
|
||||||
|
return list.stream()
|
||||||
|
.collect(Collectors.groupingBy(keyExtractor, Collectors.counting()))
|
||||||
|
.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue() > 1)
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.map(Object::toString)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public class MetricConverter {
|
|||||||
ModelResp modelResp = modelMap.get(metricDO.getModelId());
|
ModelResp modelResp = modelMap.get(metricDO.getModelId());
|
||||||
if (modelResp != null) {
|
if (modelResp != null) {
|
||||||
metricResp.setModelName(modelResp.getName());
|
metricResp.setModelName(modelResp.getName());
|
||||||
|
metricResp.setModelBizName(modelResp.getBizName());
|
||||||
metricResp.setDomainId(modelResp.getDomainId());
|
metricResp.setDomainId(modelResp.getDomainId());
|
||||||
}
|
}
|
||||||
metricResp.setIsCollect(collect != null && collect.contains(metricDO.getId()));
|
metricResp.setIsCollect(collect != null && collect.contains(metricDO.getId()));
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ public class BenchMarkDemoDataLoader {
|
|||||||
new ViewModelConfig(5L, Lists.newArrayList(8L), Lists.newArrayList()),
|
new ViewModelConfig(5L, Lists.newArrayList(8L), Lists.newArrayList()),
|
||||||
new ViewModelConfig(6L, Lists.newArrayList(9L, 10L), Lists.newArrayList()),
|
new ViewModelConfig(6L, Lists.newArrayList(9L, 10L), Lists.newArrayList()),
|
||||||
new ViewModelConfig(7L, Lists.newArrayList(11L, 12L), Lists.newArrayList()),
|
new ViewModelConfig(7L, Lists.newArrayList(11L, 12L), Lists.newArrayList()),
|
||||||
new ViewModelConfig(8L, Lists.newArrayList(13L, 14L, 15L), Lists.newArrayList(8L, 9L))
|
new ViewModelConfig(8L, Lists.newArrayList(13L, 14L), Lists.newArrayList(8L, 9L))
|
||||||
);
|
);
|
||||||
ViewDetail viewDetail = new ViewDetail();
|
ViewDetail viewDetail = new ViewDetail();
|
||||||
viewDetail.setViewModelConfigs(viewModelConfigs);
|
viewDetail.setViewModelConfigs(viewModelConfigs);
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ dean _1_2 36
|
|||||||
john _1_2 50
|
john _1_2 50
|
||||||
jack _1_2 38
|
jack _1_2 38
|
||||||
admin _1_2 70
|
admin _1_2 70
|
||||||
周杰伦 _2_7 100
|
周杰伦 _4_7 100
|
||||||
陈奕迅 _2_7 100
|
陈奕迅 _4_7 100
|
||||||
林俊杰 _2_7 100
|
林俊杰 _4_7 100
|
||||||
张碧晨 _2_7 100
|
张碧晨 _4_7 100
|
||||||
程响 _2_7 100
|
程响 _4_7 100
|
||||||
Taylor#Swift _2_7 100
|
Taylor#Swift _4_7 100
|
||||||
内地 _2_4 100
|
内地 _4_4 100
|
||||||
欧美 _2_4 100
|
欧美 _4_4 100
|
||||||
港台 _2_4 100
|
港台 _4_4 100
|
||||||
流行 _2_6 100
|
流行 _4_6 100
|
||||||
国风 _2_6 100
|
国风 _4_6 100
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
p1 _2_3 52
|
p1 _3_3 52
|
||||||
p2 _2_3 47
|
p2 _3_3 47
|
||||||
p3 _2_3 31
|
p3 _3_3 31
|
||||||
p4 _2_3 36
|
p4 _3_3 36
|
||||||
p5 _2_3 50
|
p5 _3_3 50
|
||||||
p6 _2_3 38
|
p6 _3_3 38
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
周杰伦 _2_7 9000
|
周杰伦 _4_7 9000
|
||||||
周深 _2_7 8000
|
周深 _4_7 8000
|
||||||
周传雄 _2_7 7000
|
周传雄 _4_7 7000
|
||||||
周华建 _2_7 6000
|
周华建 _4_7 6000
|
||||||
陈奕迅 _2_7 8000
|
陈奕迅 _4_7 8000
|
||||||
林俊杰 _2_7 7000
|
林俊杰 _4_7 7000
|
||||||
张碧晨 _2_7 7000
|
张碧晨 _4_7 7000
|
||||||
程响 _2_7 7000
|
程响 _4_7 7000
|
||||||
Taylor#Swift _2_7 7000
|
Taylor#Swift _4_7 7000
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
美国 _3_8 1
|
美国 _5_8 1
|
||||||
加拿大 _3_8 1
|
加拿大 _5_8 1
|
||||||
锡尔赫特、吉大港、库斯蒂亚 _3_8 1
|
锡尔赫特、吉大港、库斯蒂亚 _5_8 1
|
||||||
孟加拉国 _3_8 3
|
孟加拉国 _5_8 3
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
现代 _3_9 1
|
现代 _5_9 1
|
||||||
tagore _3_9 1
|
tagore _5_9 1
|
||||||
蓝调 _3_9 1
|
蓝调 _5_9 1
|
||||||
流行 _3_9 1
|
流行 _5_9 1
|
||||||
民间 _3_9 1
|
民间 _5_9 1
|
||||||
nazrul _3_9 1
|
nazrul _5_9 1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
美国 _3_11 1
|
美国 _6_11 1
|
||||||
印度 _3_11 2
|
印度 _6_11 2
|
||||||
英国 _3_11 1
|
英国 _6_11 1
|
||||||
孟加拉国 _3_11 2
|
孟加拉国 _6_11 2
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
男性 _3_12 3
|
男性 _6_12 3
|
||||||
女性 _3_12 3
|
女性 _6_12 3
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
mp4 _3_14 4
|
mp4 _7_14 4
|
||||||
mp3 _3_14 2
|
mp3 _7_14 2
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
美国 _3_17 1
|
美国 _8_17 1
|
||||||
印度 _3_17 2
|
印度 _8_17 2
|
||||||
英国 _3_17 1
|
英国 _8_17 1
|
||||||
孟加拉国 _3_17 2
|
孟加拉国 _8_17 2
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
英文 _3_18 2
|
英文 _8_18 2
|
||||||
孟加拉语 _3_18 4
|
孟加拉语 _8_18 4
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
阿米·奥帕尔·霍伊 _3_16 1
|
阿米·奥帕尔·霍伊 _8_16 1
|
||||||
我的爱 _3_16 1
|
我的爱 _8_16 1
|
||||||
打败它 _3_16 1
|
打败它 _8_16 1
|
||||||
阿杰伊阿卡什 _3_16 1
|
阿杰伊阿卡什 _8_16 1
|
||||||
Tumi#长袍#尼罗布 _3_16 1
|
Tumi#长袍#尼罗布 _8_16 1
|
||||||
舒克诺#帕塔尔#努普尔#帕埃 _3_16 1
|
舒克诺#帕塔尔#努普尔#帕埃 _8_16 1
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.tencent.supersonic.headless;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.request.FieldRemovedReq;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.response.MetricResp;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.response.UnAvailableItemResp;
|
||||||
|
import com.tencent.supersonic.headless.server.service.ModelService;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ModelSchemaTest extends BaseTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ModelService modelService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetUnAvailableItem() {
|
||||||
|
FieldRemovedReq fieldRemovedReq = new FieldRemovedReq();
|
||||||
|
fieldRemovedReq.setModelId(2L);
|
||||||
|
fieldRemovedReq.setFields(Lists.newArrayList("pv"));
|
||||||
|
UnAvailableItemResp unAvailableItemResp = modelService.getUnAvailableItem(fieldRemovedReq);
|
||||||
|
List<Long> expectedUnAvailableMetricId = Lists.newArrayList(1L, 3L);
|
||||||
|
List<Long> actualUnAvailableMetricId = unAvailableItemResp.getMetricResps()
|
||||||
|
.stream().map(MetricResp::getId).sorted(Comparator.naturalOrder()).collect(Collectors.toList());
|
||||||
|
Assertions.assertEquals(expectedUnAvailableMetricId, actualUnAvailableMetricId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,14 +5,14 @@ dean _1_2 36
|
|||||||
john _1_2 50
|
john _1_2 50
|
||||||
jack _1_2 38
|
jack _1_2 38
|
||||||
admin _1_2 70
|
admin _1_2 70
|
||||||
周杰伦 _2_7 100
|
周杰伦 _4_7 100
|
||||||
陈奕迅 _2_7 100
|
陈奕迅 _4_7 100
|
||||||
林俊杰 _2_7 100
|
林俊杰 _4_7 100
|
||||||
张碧晨 _2_7 100
|
张碧晨 _4_7 100
|
||||||
程响 _2_7 100
|
程响 _4_7 100
|
||||||
Taylor#Swift _2_7 100
|
Taylor#Swift _4_7 100
|
||||||
内地 _2_4 100
|
内地 _4_4 100
|
||||||
欧美 _2_4 100
|
欧美 _4_4 100
|
||||||
港台 _2_4 100
|
港台 _4_4 100
|
||||||
流行 _2_6 100
|
流行 _4_6 100
|
||||||
国风 _2_6 100
|
国风 _4_6 100
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
p1 _2_3 52
|
p1 _3_3 52
|
||||||
p2 _2_3 47
|
p2 _3_3 47
|
||||||
p3 _2_3 31
|
p3 _3_3 31
|
||||||
p4 _2_3 36
|
p4 _3_3 36
|
||||||
p5 _2_3 50
|
p5 _3_3 50
|
||||||
p6 _2_3 38
|
p6 _3_3 38
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
周杰伦 _2_7 9000
|
周杰伦 _4_7 9000
|
||||||
周深 _2_7 8000
|
周深 _4_7 8000
|
||||||
周传雄 _2_7 7000
|
周传雄 _4_7 7000
|
||||||
周华建 _2_7 6000
|
周华建 _4_7 6000
|
||||||
陈奕迅 _2_7 8000
|
陈奕迅 _4_7 8000
|
||||||
林俊杰 _2_7 7000
|
林俊杰 _4_7 7000
|
||||||
张碧晨 _2_7 7000
|
张碧晨 _4_7 7000
|
||||||
程响 _2_7 7000
|
程响 _4_7 7000
|
||||||
Taylor#Swift _2_7 7000
|
Taylor#Swift _4_7 7000
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
美国 _5_8 1
|
美国 _5_8 1
|
||||||
加拿大 _5_8 1
|
加拿大 _5_8 1
|
||||||
锡尔赫特、吉大港、库斯蒂亚 _5_8 1
|
锡尔赫特、吉大港、库斯蒂亚 _5_8 1
|
||||||
孟加拉国 _5_8 3
|
孟加拉国 _5_8 3
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ tagore _5_9 1
|
|||||||
蓝调 _5_9 1
|
蓝调 _5_9 1
|
||||||
流行 _5_9 1
|
流行 _5_9 1
|
||||||
民间 _5_9 1
|
民间 _5_9 1
|
||||||
nazrul _5_9 1
|
nazrul _5_9 1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
美国 _6_10 1
|
美国 _6_11 1
|
||||||
印度 _6_10 2
|
印度 _6_11 2
|
||||||
英国 _6_10 1
|
英国 _6_11 1
|
||||||
孟加拉国 _6_10 2
|
孟加拉国 _6_11 2
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
男性 _6_11 3
|
男性 _6_12 3
|
||||||
女性 _6_11 3
|
女性 _6_12 3
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
mp4 _7_14 4
|
mp4 _7_14 4
|
||||||
mp3 _7_14 2
|
mp3 _7_14 2
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
美国 _8_16 1
|
美国 _8_17 1
|
||||||
印度 _8_16 2
|
印度 _8_17 2
|
||||||
英国 _8_16 1
|
英国 _8_17 1
|
||||||
孟加拉国 _8_16 2
|
孟加拉国 _8_17 2
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
英文 _8_17 2
|
英文 _8_18 2
|
||||||
孟加拉语 _8_17 4
|
孟加拉语 _8_18 4
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
阿米·奥帕尔·霍伊 _8_19 1
|
阿米·奥帕尔·霍伊 _8_16 1
|
||||||
我的爱 _8_19 1
|
我的爱 _8_16 1
|
||||||
打败它 _8_19 1
|
打败它 _8_16 1
|
||||||
阿杰伊阿卡什 _8_19 1
|
阿杰伊阿卡什 _8_16 1
|
||||||
Tumi#长袍#尼罗布 _8_19 1
|
Tumi#长袍#尼罗布 _8_16 1
|
||||||
舒克诺#帕塔尔#努普尔#帕埃 _8_19 1
|
舒克诺#帕塔尔#努普尔#帕埃 _8_16 1
|
||||||
|
|||||||
Reference in New Issue
Block a user