[improvement][project] supersonic 0.6.0 version update (#16)

Co-authored-by: lexluo <lexluo@tencent.com>
This commit is contained in:
lexluo09
2023-07-16 21:32:33 +08:00
committed by GitHub
parent a0869dc7bd
commit 041daad1e4
261 changed files with 12031 additions and 3266 deletions

2
.gitignore vendored
View File

@@ -14,4 +14,4 @@ assembly/runtime/*
*.umi/ *.umi/
/assembly/deploy /assembly/deploy
/runtime /runtime
.flattened-pom.xml **/.flattened-pom.xml

View File

@@ -7,4 +7,15 @@ davinci 0.3.0 change log
6) modify permission process 6) modify permission process
7) optimize css style 7) optimize css style
8) optimize filter 8) optimize filter
9) delete view module 9) delete view module
supersonic 0.6.0 change log
1) add llm parser and llm api server
2) support fuzzy mapping
3) support query filter and domain filter in query and search
4) support standalone mode
5) add dsl query in semantic
6) code architecture adjustment in semantic and chat
7) add unit testing and integration testing
8) support dimension and metric alias

View File

@@ -4,6 +4,7 @@ English | [中文](README_CN.md)
**SuperSonic is an out-of-the-box yet highly extensible framework for building a data chatbot**. SuperSonic provides a chat interface that empowers users to query data using natural language and visualize the results with suitable charts. To enable such experience, the only thing necessary is to define logical semantic models (metrics, dimensions, relationships, etc) on top of physical data models, and no data modification or copying is required. Meanwhile SuperSonic is designed to be plugable, allowing new functionalities to be added through plugins and core components to be integrated into other systems. **SuperSonic is an out-of-the-box yet highly extensible framework for building a data chatbot**. SuperSonic provides a chat interface that empowers users to query data using natural language and visualize the results with suitable charts. To enable such experience, the only thing necessary is to define logical semantic models (metrics, dimensions, relationships, etc) on top of physical data models, and no data modification or copying is required. Meanwhile SuperSonic is designed to be plugable, allowing new functionalities to be added through plugins and core components to be integrated into other systems.
<img src="./docs/images/supersonic_demo.gif" align="center"/> <img src="./docs/images/supersonic_demo.gif" align="center"/>
## Motivation ## Motivation
@@ -28,8 +29,10 @@ With these ideas in mind, we developed SuperSonic as a reference implementation
SuperSonic is composed of two layers: supersonic-chat and supersonic-semantic. The chat layer is responsible for converting **natural language query** into semantic query (also known as DSL query), whereas the semantic layer is responsible for converting DSL query into **SQL query**. The high-level architecture and main process flow is shown in below diagram: SuperSonic is composed of two layers: supersonic-chat and supersonic-semantic. The chat layer is responsible for converting **natural language query** into semantic query (also known as DSL query), whereas the semantic layer is responsible for converting DSL query into **SQL query**. The high-level architecture and main process flow is shown in below diagram:
<img src="./docs/images/supersonic_components.png" height="80%" width="80%" align="center"/> <img src="./docs/images/supersonic_components.png" height="80%" width="80%" align="center"/>
### Chat Layer ### Chat Layer
The chat layer contains four core components: The chat layer contains four core components:
@@ -64,4 +67,4 @@ SuperSonic comes with sample semantic models as well as chat conversations that
## How to Build ## How to Build
Pull the source code and run script "assembly/bin/build-standalone.sh" to build packages in the standalone mode. Pull the source code and run script "assembly/bin/build-standalone.sh" to build packages in the standalone mode.

12
assembly/bin/build-chat.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/runtime
buildDir=$baseDir/build
cd $baseDir
#1. move package to build
cp $baseDir/../launchers/chat/target/*.tar.gz ${buildDir}/supersonic-chat.tar.gz

View File

@@ -7,18 +7,17 @@ buildDir=$baseDir/build
cd $baseDir cd $baseDir
#1. build semantic chat service #1. build semantic service
rm -fr ${buildDir}/*.tar.gz rm -fr ${buildDir}/*.tar.gz
rm -fr dist rm -fr dist
mvn -f $baseDir/../ clean package -DskipTests mvn -f $baseDir/../ clean package -DskipTests
#2. move package to build #2. move package to build
cp $baseDir/../launchers/chat/target/*.tar.gz ${buildDir}/supersonic-chat.tar.gz
cp $baseDir/../launchers/semantic/target/*.tar.gz ${buildDir}/supersonic-semantic.tar.gz cp $baseDir/../launchers/semantic/target/*.tar.gz ${buildDir}/supersonic-semantic.tar.gz
#3. build webapp #3. build webapp
chmod +x $baseDir/../webapp/start-fe-prod.sh chmod +x $baseDir/../webapp/start-fe-prod.sh
cd ../webapp cd ../webapp
sh ./start-fe-prod.sh sh ./start-fe-prod.sh
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/ cp -fr ./supersonic-webapp.tar.gz ${buildDir}/

35
assembly/bin/start-chat.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
sbinDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $sbinDir/../)
runtimeDir=$baseDir/../runtime
buildDir=$baseDir/build
cd $baseDir
#2. package lib
tar -zxvf ${buildDir}/supersonic-chat.tar.gz -C ${runtimeDir}
mv ${runtimeDir}/launchers-chat-* ${runtimeDir}/supersonic-chat
tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
mkdir -p ${runtimeDir}/supersonic-chat/webapp
cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-chat/webapp
rm -fr ${buildDir}/supersonic-webapp
json=$(cat ${runtimeDir}/supersonic-chat/webapp/supersonic.config.json)
json=$(echo $json | jq '.env="chat"')
echo $json > ${runtimeDir}/supersonic-chat/webapp/supersonic.config.json
#3. start service
#3.1 start chat service
echo ${runtimeDir}
sh ${runtimeDir}/supersonic-chat/bin/service.sh restart
#3.2 start llm service
sh ${runtimeDir}/supersonic-chat/llm/bin/service.sh restart

View File

@@ -14,23 +14,23 @@ rm -fr ${runtimeDir}/*
#2. package lib #2. package lib
tar -zxvf ${buildDir}/supersonic-semantic.tar.gz -C ${runtimeDir} tar -zxvf ${buildDir}/supersonic-semantic.tar.gz -C ${runtimeDir}
tar -zxvf ${buildDir}/supersonic-chat.tar.gz -C ${runtimeDir}
mv ${runtimeDir}/launchers-chat-* ${runtimeDir}/supersonic-chat
mv ${runtimeDir}/launchers-semantic-* ${runtimeDir}/supersonic-semantic mv ${runtimeDir}/launchers-semantic-* ${runtimeDir}/supersonic-semantic
tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir} tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
mkdir -p ${runtimeDir}/supersonic-semantic/webapp mkdir -p ${runtimeDir}/supersonic-semantic/webapp
mkdir -p ${runtimeDir}/supersonic-chat/webapp
cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-semantic/webapp cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-semantic/webapp
cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-chat/webapp
rm -fr ${buildDir}/supersonic-webapp rm -fr ${buildDir}/supersonic-webapp
json=$(cat ${runtimeDir}/supersonic-semantic/webapp/supersonic.config.json)
json=$(echo $json | jq '.env="semantic"')
echo $json > ${runtimeDir}/supersonic-semantic/webapp/supersonic.config.json
#3. start service #3. start service
sh ${runtimeDir}/supersonic-semantic/bin/service.sh restart sh ${runtimeDir}/supersonic-semantic/bin/service.sh restart
sleep 5
sh ${runtimeDir}/supersonic-chat/bin/service.sh restart

View File

@@ -26,5 +26,7 @@ cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-standalone/weba
rm -fr ${buildDir}/supersonic-webapp rm -fr ${buildDir}/supersonic-webapp
#3. start service #3. start service
#start standalone service
sh ${runtimeDir}/supersonic-standalone/bin/service.sh restart sh ${runtimeDir}/supersonic-standalone/bin/service.sh restart
#start llm service
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh restart

View File

@@ -28,6 +28,12 @@
<include>*.jar</include> <include>*.jar</include>
</includes> </includes>
</fileSet> </fileSet>
<fileSet>
<directory>${project.basedir}/../../chat/core/src/main/python</directory>
<outputDirectory>llm</outputDirectory>
<fileMode>0777</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
</fileSets> </fileSets>
<dependencySets> <dependencySets>

View File

@@ -2,6 +2,7 @@ package com.tencent.supersonic.auth.authentication.domain.interceptor;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig; import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword; import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.authentication.application.UserServiceImpl; import com.tencent.supersonic.auth.authentication.application.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils; import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
@@ -27,11 +28,12 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
userTokenUtils = ContextUtils.getBean(UserTokenUtils.class); userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class); s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
if (!authenticationConfig.isEnabled()) { if (!authenticationConfig.isEnabled()) {
setFakerUser(request);
return true; return true;
} }
if (isInternalRequest(request)) { if (isInternalRequest(request)) {
String token = userTokenUtils.generateAdminToken(); setFakerUser(request);
reflectSetparam(request, authenticationConfig.getTokenHttpHeaderKey(), token); return true;
} }
HandlerMethod handlerMethod = (HandlerMethod) handler; HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod(); Method method = handlerMethod.getMethod();
@@ -47,15 +49,25 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
UserWithPassword user = userTokenUtils.getUserWithPassword(request); UserWithPassword user = userTokenUtils.getUserWithPassword(request);
if (StringUtils.isNotBlank(user.getName())) { if (StringUtils.isNotBlank(user.getName())) {
ThreadContext threadContext = ThreadContext.builder() setContext(user.getName(), request);
.token(request.getHeader(authenticationConfig.getTokenHttpHeaderKey()))
.userName(user.getName())
.build();
s2ThreadContext.set(threadContext);
return true; return true;
} }
throw new AccessException("authentication failed, please login"); throw new AccessException("authentication failed, please login");
} }
private void setFakerUser(HttpServletRequest request) {
String token = userTokenUtils.generateAdminToken();
reflectSetparam(request, authenticationConfig.getTokenHttpHeaderKey(), token);
setContext(User.getFakeUser().getName(), request);
}
private void setContext(String userName, HttpServletRequest request) {
ThreadContext threadContext = ThreadContext.builder()
.token(request.getHeader(authenticationConfig.getTokenHttpHeaderKey()))
.userName(userName)
.build();
s2ThreadContext.set(threadContext);
}
} }

View File

@@ -1,8 +1,10 @@
package com.tencent.supersonic.chat.api.component; package com.tencent.supersonic.chat.api.component;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp; import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp; import com.tencent.supersonic.semantic.api.core.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.core.response.*;
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq; import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq; import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
@@ -26,8 +28,24 @@ public interface SemanticLayer {
QueryResultWithSchemaResp queryBySql(QuerySqlReq querySqlReq, User user); QueryResultWithSchemaResp queryBySql(QuerySqlReq querySqlReq, User user);
DomainSchemaResp getDomainSchemaInfo(Long domain); DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable);
List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids); List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids);
List<DomainResp> getDomainListForViewer();
List<DomainResp> getDomainListForAdmin();
PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd);
PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd);
// PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd);
//
// PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd);
//
// List<DomainResp> getDomainListForAdmin();
//
// List<DomainResp> getDomainListForViewer();
} }

View File

@@ -3,32 +3,25 @@ package com.tencent.supersonic.chat.application;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.component.SemanticLayer; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfig; import com.tencent.supersonic.chat.domain.pojo.config.*;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBase;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetric;
import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo;
import com.tencent.supersonic.chat.domain.pojo.config.ItemVisibilityInfo;
import com.tencent.supersonic.chat.domain.pojo.config.KnowledgeInfo;
import com.tencent.supersonic.chat.domain.repository.ChatConfigRepository;
import com.tencent.supersonic.chat.domain.service.ConfigService;
import com.tencent.supersonic.chat.domain.utils.ChatConfigUtils;
import com.tencent.supersonic.chat.domain.utils.ComponentFactory; import com.tencent.supersonic.chat.domain.utils.ComponentFactory;
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils; import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.common.util.json.JsonUtil;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.DomainResp; import com.tencent.supersonic.semantic.api.core.response.DomainResp;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import com.tencent.supersonic.chat.domain.repository.ChatConfigRepository;
import com.tencent.supersonic.chat.domain.service.ConfigService;
import com.tencent.supersonic.chat.domain.utils.ChatConfigUtils;
import com.tencent.supersonic.common.util.json.JsonUtil;
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.Objects; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
@@ -40,33 +33,31 @@ import org.springframework.util.CollectionUtils;
@Service @Service
public class ConfigServiceImpl implements ConfigService { public class ConfigServiceImpl implements ConfigService {
private final ChatConfigRepository chaConfigRepository; private final ChatConfigRepository chatConfigRepository;
private final ChatConfigUtils chatConfigUtils; private final ChatConfigUtils chatConfigUtils;
private final DefaultSemanticInternalUtils defaultSemanticUtils; private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
public ConfigServiceImpl(ChatConfigRepository chaConfigRepository, public ConfigServiceImpl(ChatConfigRepository chatConfigRepository,
ChatConfigUtils chatConfigUtils, ChatConfigUtils chatConfigUtils) {
@Lazy DefaultSemanticInternalUtils defaultSemanticUtils) { this.chatConfigRepository = chatConfigRepository;
this.chaConfigRepository = chaConfigRepository;
this.chatConfigUtils = chatConfigUtils; this.chatConfigUtils = chatConfigUtils;
this.defaultSemanticUtils = defaultSemanticUtils;
} }
@Override @Override
public Long addConfig(ChatConfigBase configBaseCmd, User user) { public Long addConfig(ChatConfigBaseReq configBaseCmd, User user) {
log.info("[create domain extend] object:{}", JsonUtil.toString(configBaseCmd, true)); log.info("[create domain extend] object:{}", JsonUtil.toString(configBaseCmd, true));
duplicateCheck(configBaseCmd.getDomainId()); duplicateCheck(configBaseCmd.getDomainId());
permissionCheckLogic(configBaseCmd.getDomainId(), user.getName()); permissionCheckLogic(configBaseCmd.getDomainId(), user.getName());
ChatConfig chaConfig = chatConfigUtils.newChatConfig(configBaseCmd, user); ChatConfig chaConfig = chatConfigUtils.newChatConfig(configBaseCmd, user);
chaConfigRepository.createConfig(chaConfig); Long id = chatConfigRepository.createConfig(chaConfig);
return chaConfig.getDomainId(); return id;
} }
private void duplicateCheck(Long domainId) { private void duplicateCheck(Long domainId) {
ChatConfigFilter filter = new ChatConfigFilter(); ChatConfigFilter filter = new ChatConfigFilter();
filter.setDomainId(domainId); filter.setDomainId(domainId);
List<ChatConfigInfo> chaConfigDescList = chaConfigRepository.getChatConfig(filter); List<ChatConfigResp> chaConfigDescList = chatConfigRepository.getChatConfig(filter);
if (!CollectionUtils.isEmpty(chaConfigDescList)) { if (!CollectionUtils.isEmpty(chaConfigDescList)) {
throw new RuntimeException("chat config existed, no need to add repeatedly"); throw new RuntimeException("chat config existed, no need to add repeatedly");
} }
@@ -74,16 +65,16 @@ public class ConfigServiceImpl implements ConfigService {
@Override @Override
public Long editConfig(ChatConfigEditReq configEditCmd, User user) { public Long editConfig(ChatConfigEditReqReq configEditCmd, User user) {
log.info("[edit domain extend] object:{}", JsonUtil.toString(configEditCmd, true)); log.info("[edit domain extend] object:{}", JsonUtil.toString(configEditCmd, true));
if (Objects.isNull(configEditCmd) || Objects.isNull(configEditCmd.getId()) && Objects.isNull( if (Objects.isNull(configEditCmd) || Objects.isNull(configEditCmd.getId()) && Objects.isNull(
configEditCmd.getDomainId())) { configEditCmd.getDomainId())) {
throw new RuntimeException("editConfig, id and domainId are not allowed to be empty at the same time"); throw new RuntimeException("editConfig, id and domainId are not allowed to be empty at the same time");
} }
permissionCheckLogic(configEditCmd.getDomainId(), user.getName()); permissionCheckLogic(configEditCmd.getDomainId(), user.getName());
ChatConfig chaConfig = chatConfigUtils.editChaConfig(configEditCmd, user); ChatConfig chaConfig = chatConfigUtils.editChatConfig(configEditCmd, user);
chaConfigRepository.updateConfig(chaConfig); chatConfigRepository.updateConfig(chaConfig);
return configEditCmd.getDomainId(); return configEditCmd.getId();
} }
@@ -96,98 +87,34 @@ public class ConfigServiceImpl implements ConfigService {
} }
@Override @Override
public List<ChatConfigInfo> search(ChatConfigFilter filter, User user) { public List<ChatConfigResp> search(ChatConfigFilter filter, User user) {
log.info("[search domain extend] object:{}", JsonUtil.toString(filter, true)); log.info("[search domain extend] object:{}", JsonUtil.toString(filter, true));
List<ChatConfigInfo> chaConfigDescList = chaConfigRepository.getChatConfig(filter); List<ChatConfigResp> chaConfigDescList = chatConfigRepository.getChatConfig(filter);
return chaConfigDescList; return chaConfigDescList;
} }
public ChatConfigInfo fetchConfigByDomainId(Long domainId) { @Override
return chaConfigRepository.getConfigByDomainId(domainId); public ChatConfigResp fetchConfigByDomainId(Long domainId) {
} return chatConfigRepository.getConfigByDomainId(domainId);
public EntityRichInfo fetchEntityDescByDomainId(Long domainId) {
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
ChatConfigInfo chaConfigDesc = chaConfigRepository.getConfigByDomainId(domainId);
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(domainId);
return fetchEntityDescByConfig(chaConfigDesc, domainSchemaDesc);
}
public EntityRichInfo fetchEntityDescByConfig(ChatConfigInfo chatConfigDesc, DomainSchemaResp domain) {
Long domainId = chatConfigDesc.getDomainId();
EntityRichInfo entityDesc = new EntityRichInfo();
if (Objects.isNull(chatConfigDesc) || Objects.isNull(chatConfigDesc.getEntity())) {
log.info("domainId:{}, entityDesc info is null", domainId);
return entityDesc;
}
entityDesc.setDomainId(domain.getId());
entityDesc.setDomainBizName(domain.getBizName());
entityDesc.setDomainName(domain.getName());
entityDesc.setNames(chatConfigDesc.getEntity().getNames());
entityDesc.setEntityIds(chatConfigUtils.generateDimDesc(chatConfigDesc.getEntity().getEntityIds(), domain));
entityDesc.setEntityInternalDetailDesc(
chatConfigUtils.generateEntityDetailData(chatConfigDesc.getEntity().getDetailData(), domain));
return entityDesc;
} }
public List<DefaultMetric> fetchDefaultMetricDescByDomainId(Long domainId) { private ItemVisibilityInfo fetchVisibilityDescByConfig(ItemVisibility visibility,
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer(); DomainSchemaResp domainSchemaDesc) {
ChatConfigInfo chatConfigDesc = chaConfigRepository.getConfigByDomainId(domainId);
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(domainId);
return fetchDefaultMetricDescByConfig(chatConfigDesc, domainSchemaDesc);
}
public List<DefaultMetric> fetchDefaultMetricDescByConfig(ChatConfigInfo chatConfigDesc, DomainSchemaResp domain) {
Long domainId = chatConfigDesc.getDomainId();
List<DefaultMetric> defaultMetricDescList = new ArrayList<>();
if (Objects.isNull(chatConfigDesc) || CollectionUtils.isEmpty(chatConfigDesc.getDefaultMetrics())) {
log.info("domainId:{}, defaultMetricDescList info is null", domainId);
return defaultMetricDescList;
}
List<Long> metricIds = chatConfigDesc.getDefaultMetrics().stream()
.map(defaultMetricInfo -> defaultMetricInfo.getMetricId()).collect(Collectors.toList());
Map<Long, MetricSchemaResp> metricIdAndDescPair = chatConfigUtils.generateMetricIdAndDescPair(metricIds,
domain);
chatConfigDesc.getDefaultMetrics().stream().forEach(defaultMetricInfo -> {
DefaultMetric defaultMetricDesc = new DefaultMetric();
BeanUtils.copyProperties(defaultMetricInfo, defaultMetricDesc);
if (metricIdAndDescPair.containsKey(defaultMetricInfo.getMetricId())) {
MetricSchemaResp metricDesc = metricIdAndDescPair.get(defaultMetricInfo.getMetricId());
defaultMetricDesc.setBizName(metricDesc.getBizName());
defaultMetricDesc.setName(metricDesc.getName());
}
defaultMetricDescList.add(defaultMetricDesc);
});
return defaultMetricDescList;
}
public ItemVisibilityInfo fetchVisibilityDescByDomainId(Long domainId) {
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
ChatConfigInfo chatConfigDesc = chaConfigRepository.getConfigByDomainId(domainId);
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(domainId);
return fetchVisibilityDescByConfig(chatConfigDesc, domainSchemaDesc);
}
private ItemVisibilityInfo fetchVisibilityDescByConfig(ChatConfigInfo chatConfigDesc,
DomainSchemaResp domainSchemaDesc) {
ItemVisibilityInfo itemVisibilityDesc = new ItemVisibilityInfo(); ItemVisibilityInfo itemVisibilityDesc = new ItemVisibilityInfo();
Long domainId = chatConfigDesc.getDomainId();
List<Long> dimIdAllList = chatConfigUtils.generateAllDimIdList(domainSchemaDesc); List<Long> dimIdAllList = chatConfigUtils.generateAllDimIdList(domainSchemaDesc);
List<Long> metricIdAllList = chatConfigUtils.generateAllMetricIdList(domainSchemaDesc); List<Long> metricIdAllList = chatConfigUtils.generateAllMetricIdList(domainSchemaDesc);
List<Long> blackDimIdList = new ArrayList<>(); List<Long> blackDimIdList = new ArrayList<>();
List<Long> blackMetricIdList = new ArrayList<>(); List<Long> blackMetricIdList = new ArrayList<>();
if (Objects.nonNull(chatConfigDesc.getVisibility())) { if (Objects.nonNull(visibility)) {
if (!CollectionUtils.isEmpty(chatConfigDesc.getVisibility().getBlackDimIdList())) { if (!CollectionUtils.isEmpty(visibility.getBlackDimIdList())) {
blackDimIdList.addAll(chatConfigDesc.getVisibility().getBlackDimIdList()); blackDimIdList.addAll(visibility.getBlackDimIdList());
} }
if (!CollectionUtils.isEmpty(chatConfigDesc.getVisibility().getBlackMetricIdList())) { if (!CollectionUtils.isEmpty(visibility.getBlackMetricIdList())) {
blackMetricIdList.addAll(chatConfigDesc.getVisibility().getBlackMetricIdList()); blackMetricIdList.addAll(visibility.getBlackMetricIdList());
} }
} }
List<Long> whiteMetricIdList = metricIdAllList.stream().filter(id -> !blackMetricIdList.contains(id)) List<Long> whiteMetricIdList = metricIdAllList.stream().filter(id -> !blackMetricIdList.contains(id))
@@ -204,31 +131,110 @@ public class ConfigServiceImpl implements ConfigService {
} }
@Override @Override
public ChatConfigRichInfo getConfigRichInfo(Long domainId) { public ChatConfigRichResp getConfigRichInfo(Long domainId) {
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer(); ChatConfigRichResp chatConfigRichResp = new ChatConfigRichResp();
ChatConfigRichInfo chaConfigRichDesc = new ChatConfigRichInfo(); ChatConfigResp chatConfigResp = chatConfigRepository.getConfigByDomainId(domainId);
ChatConfigInfo chatConfigDesc = chaConfigRepository.getConfigByDomainId(domainId); if (Objects.isNull(chatConfigResp)) {
if (Objects.isNull(chatConfigDesc)) {
log.info("there is no chatConfigDesc for domainId:{}", domainId); log.info("there is no chatConfigDesc for domainId:{}", domainId);
return chaConfigRichDesc; return chatConfigRichResp;
} }
BeanUtils.copyProperties(chatConfigDesc, chaConfigRichDesc); BeanUtils.copyProperties(chatConfigResp, chatConfigRichResp);
DomainSchemaResp domainSchemaInfo = semanticLayer.getDomainSchemaInfo(domainId); SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
chaConfigRichDesc.setBizName(domainSchemaInfo.getBizName()); DomainSchemaResp domainSchemaInfo = semanticLayer.getDomainSchemaInfo(domainId, false);
chaConfigRichDesc.setName(domainSchemaInfo.getName()); chatConfigRichResp.setBizName(domainSchemaInfo.getBizName());
chatConfigRichResp.setDomainName(domainSchemaInfo.getName());
chaConfigRichDesc.setKnowledgeInfos( chatConfigRichResp.setChatAggRichConfig(fillChatAggRichConfig(domainSchemaInfo, chatConfigResp));
fillKnowledgeBizName(chaConfigRichDesc.getKnowledgeInfos(), domainSchemaInfo)); chatConfigRichResp.setChatDetailRichConfig(fillChatDetailRichConfig(domainSchemaInfo, chatConfigRichResp, chatConfigResp));
chaConfigRichDesc.setDefaultMetrics(fetchDefaultMetricDescByConfig(chatConfigDesc, domainSchemaInfo));
chaConfigRichDesc.setVisibility(fetchVisibilityDescByConfig(chatConfigDesc, domainSchemaInfo));
chaConfigRichDesc.setEntity(fetchEntityDescByConfig(chatConfigDesc, domainSchemaInfo));
return chaConfigRichDesc; return chatConfigRichResp;
} }
private ChatDetailRichConfig fillChatDetailRichConfig(DomainSchemaResp domainSchemaInfo, ChatConfigRichResp chatConfigRichResp, ChatConfigResp chatConfigResp) {
if (Objects.isNull(chatConfigResp) || Objects.isNull(chatConfigResp.getChatDetailConfig())) {
return null;
}
ChatDetailRichConfig detailRichConfig = new ChatDetailRichConfig();
ChatDetailConfig chatDetailConfig = chatConfigResp.getChatDetailConfig();
detailRichConfig.setVisibility(fetchVisibilityDescByConfig(chatDetailConfig.getVisibility(), domainSchemaInfo));
detailRichConfig.setKnowledgeInfos(fillKnowledgeBizName(chatDetailConfig.getKnowledgeInfos(), domainSchemaInfo));
detailRichConfig.setGlobalKnowledgeConfig(chatDetailConfig.getGlobalKnowledgeConfig());
detailRichConfig.setChatDefaultConfig(fetchDefaultConfig(chatDetailConfig.getChatDefaultConfig(), domainSchemaInfo));
detailRichConfig.setEntity(generateRichEntity(chatDetailConfig.getEntity(), domainSchemaInfo));
return detailRichConfig;
}
private EntityRichInfo generateRichEntity(Entity entity, DomainSchemaResp domainSchemaInfo) {
EntityRichInfo entityRichInfo = new EntityRichInfo();
if (Objects.isNull(entity) || Objects.isNull(entity.getEntityId())) {
return entityRichInfo;
}
BeanUtils.copyProperties(entity, entityRichInfo);
Map<Long, DimSchemaResp> dimIdAndRespPair = domainSchemaInfo.getDimensions().stream()
.collect(Collectors.toMap(DimSchemaResp::getId, Function.identity()));
entityRichInfo.setDimItem(dimIdAndRespPair.get(entity.getEntityId()));
return entityRichInfo;
}
private ChatAggRichConfig fillChatAggRichConfig(DomainSchemaResp domainSchemaInfo, ChatConfigResp chatConfigResp) {
if (Objects.isNull(chatConfigResp) || Objects.isNull(chatConfigResp.getChatAggConfig())) {
return null;
}
ChatAggConfig chatAggConfig = chatConfigResp.getChatAggConfig();
ChatAggRichConfig chatAggRichConfig = new ChatAggRichConfig();
chatAggRichConfig.setVisibility(fetchVisibilityDescByConfig(chatAggConfig.getVisibility(), domainSchemaInfo));
chatAggRichConfig.setKnowledgeInfos(fillKnowledgeBizName(chatAggConfig.getKnowledgeInfos(), domainSchemaInfo));
chatAggRichConfig.setGlobalKnowledgeConfig(chatAggConfig.getGlobalKnowledgeConfig());
chatAggRichConfig.setChatDefaultConfig(fetchDefaultConfig(chatAggConfig.getChatDefaultConfig(), domainSchemaInfo));
return chatAggRichConfig;
}
private ChatDefaultRichConfig fetchDefaultConfig(ChatDefaultConfig chatDefaultConfig, DomainSchemaResp domainSchemaInfo) {
ChatDefaultRichConfig defaultRichConfig = new ChatDefaultRichConfig();
if (Objects.isNull(chatDefaultConfig)) {
return defaultRichConfig;
}
BeanUtils.copyProperties(chatDefaultConfig, defaultRichConfig);
Map<Long, DimSchemaResp> dimIdAndRespPair = domainSchemaInfo.getDimensions().stream()
.collect(Collectors.toMap(DimSchemaResp::getId, Function.identity()));
Map<Long, MetricSchemaResp> metricIdAndRespPair = domainSchemaInfo.getMetrics().stream()
.collect(Collectors.toMap(MetricSchemaResp::getId, Function.identity()));
List<SchemaItem> dimensions = new ArrayList<>();
List<SchemaItem> metrics = new ArrayList<>();
if (!CollectionUtils.isEmpty(chatDefaultConfig.getDimensionIds())) {
chatDefaultConfig.getDimensionIds().stream().forEach(dimId -> {
DimSchemaResp dimSchemaResp = dimIdAndRespPair.get(dimId);
SchemaItem dimSchema = new SchemaItem();
BeanUtils.copyProperties(dimSchemaResp, dimSchema);
dimensions.add(dimSchema);
});
}
if (!CollectionUtils.isEmpty(chatDefaultConfig.getMetricIds())) {
chatDefaultConfig.getMetricIds().stream().forEach(metricId -> {
MetricSchemaResp metricSchemaResp = metricIdAndRespPair.get(metricId);
SchemaItem metricSchema = new SchemaItem();
BeanUtils.copyProperties(metricSchemaResp, metricSchema);
metrics.add(metricSchema);
});
}
defaultRichConfig.setDimensions(dimensions);
defaultRichConfig.setMetrics(metrics);
return defaultRichConfig;
}
private List<KnowledgeInfo> fillKnowledgeBizName(List<KnowledgeInfo> knowledgeInfos, private List<KnowledgeInfo> fillKnowledgeBizName(List<KnowledgeInfo> knowledgeInfos,
DomainSchemaResp domainSchemaInfo) { DomainSchemaResp domainSchemaInfo) {
if (CollectionUtils.isEmpty(knowledgeInfos)) { if (CollectionUtils.isEmpty(knowledgeInfos)) {
return new ArrayList<>(); return new ArrayList<>();
} }
@@ -240,30 +246,21 @@ public class ConfigServiceImpl implements ConfigService {
if (Objects.nonNull(dimSchemaResp)) { if (Objects.nonNull(dimSchemaResp)) {
knowledgeInfo.setBizName(dimSchemaResp.getBizName()); knowledgeInfo.setBizName(dimSchemaResp.getBizName());
} }
if (CollectionUtils.isEmpty(knowledgeInfo.getBlackList())) {
knowledgeInfo.setBlackList(new ArrayList<>());
}
if (CollectionUtils.isEmpty(knowledgeInfo.getRuleList())) {
knowledgeInfo.setRuleList(new ArrayList<>());
}
if (CollectionUtils.isEmpty(knowledgeInfo.getWhiteList())) {
knowledgeInfo.setWhiteList(new ArrayList<>());
}
} }
}); });
return knowledgeInfos; return knowledgeInfos;
} }
@Override @Override
public List<ChatConfigRichInfo> getAllChatRichConfig() { public List<ChatConfigRichResp> getAllChatRichConfig() {
List<ChatConfigRichInfo> chatConfigRichInfoList = new ArrayList<>(); List<ChatConfigRichResp> chatConfigRichInfoList = new ArrayList<>();
List<DomainResp> domainRespList = defaultSemanticUtils.getDomainListForAdmin(); List<DomainResp> domainRespList = semanticLayer.getDomainListForAdmin();
domainRespList.stream().forEach(domainResp -> { domainRespList.stream().forEach(domainResp -> {
ChatConfigRichInfo chatConfigRichInfo = getConfigRichInfo(domainResp.getId()); ChatConfigRichResp chatConfigRichInfo = getConfigRichInfo(domainResp.getId());
if (Objects.nonNull(chatConfigRichInfo)) { if (Objects.nonNull(chatConfigRichInfo)) {
chatConfigRichInfoList.add(chatConfigRichInfo); chatConfigRichInfoList.add(chatConfigRichInfo);
} }
}); });
return chatConfigRichInfoList; return chatConfigRichInfoList;
} }
} }

View File

@@ -8,15 +8,14 @@ import com.tencent.supersonic.chat.api.pojo.DomainInfo;
import com.tencent.supersonic.chat.api.pojo.EntityInfo; import com.tencent.supersonic.chat.api.pojo.EntityInfo;
import com.tencent.supersonic.chat.api.pojo.Filter; import com.tencent.supersonic.chat.api.pojo.Filter;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo; import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatDefaultRichConfig;
import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo;
import com.tencent.supersonic.chat.domain.utils.ComponentFactory; import com.tencent.supersonic.chat.domain.utils.ComponentFactory;
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
import com.tencent.supersonic.chat.domain.utils.SchemaInfoConverter; import com.tencent.supersonic.chat.domain.utils.SchemaInfoConverter;
import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.DateConf;
import com.tencent.supersonic.common.pojo.SchemaItem; import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp; import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp;
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum; import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
import java.util.ArrayList; import java.util.ArrayList;
@@ -37,7 +36,7 @@ public class DomainEntityService {
private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer(); private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
@Autowired @Autowired
private DefaultSemanticInternalUtils defaultSemanticUtils; private ConfigServiceImpl configService;
public EntityInfo getEntityInfo(SemanticParseInfo parseInfo, User user) { public EntityInfo getEntityInfo(SemanticParseInfo parseInfo, User user) {
if (parseInfo != null && parseInfo.getDomainId() > 0) { if (parseInfo != null && parseInfo.getDomainId() > 0) {
@@ -77,42 +76,55 @@ public class DomainEntityService {
} }
public EntityInfo getEntityInfo(Long domain) { public EntityInfo getEntityInfo(Long domain) {
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(domain); ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(domain);
return getEntityInfo(chaConfigRichDesc.getEntity()); if (Objects.isNull(chaConfigRichDesc) || Objects.isNull(chaConfigRichDesc.getChatDetailRichConfig())) {
return new EntityInfo();
}
return getEntityInfo(chaConfigRichDesc);
} }
private EntityInfo getEntityInfo(EntityRichInfo entityDesc) { private EntityInfo getEntityInfo(ChatConfigRichResp chaConfigRichDesc) {
EntityInfo entityInfo = new EntityInfo();
if (entityDesc != null && Objects.nonNull(entityDesc.getDomainId())) { EntityInfo entityInfo = new EntityInfo();
EntityRichInfo entityDesc = chaConfigRichDesc.getChatDetailRichConfig().getEntity();
if (entityDesc != null && Objects.nonNull(chaConfigRichDesc.getDomainId())) {
DomainInfo domainInfo = new DomainInfo(); DomainInfo domainInfo = new DomainInfo();
domainInfo.setItemId(Integer.valueOf(entityDesc.getDomainId().intValue())); domainInfo.setItemId(Integer.valueOf(chaConfigRichDesc.getDomainId().intValue()));
domainInfo.setName(entityDesc.getDomainName()); domainInfo.setName(chaConfigRichDesc.getDomainName());
domainInfo.setWords(entityDesc.getNames()); domainInfo.setWords(entityDesc.getNames());
domainInfo.setBizName(entityDesc.getDomainBizName()); domainInfo.setBizName(chaConfigRichDesc.getBizName());
if (entityDesc.getEntityIds().size() > 0) { if (Objects.nonNull(entityDesc.getDimItem())) {
domainInfo.setPrimaryEntityBizName(entityDesc.getEntityIds().get(0).getBizName()); domainInfo.setPrimaryEntityBizName(entityDesc.getDimItem().getBizName());
} }
entityInfo.setDomainInfo(domainInfo); entityInfo.setDomainInfo(domainInfo);
List<DataInfo> dimensions = new ArrayList<>(); List<DataInfo> dimensions = new ArrayList<>();
List<DataInfo> metrics = new ArrayList<>(); List<DataInfo> metrics = new ArrayList<>();
if (entityDesc.getEntityInternalDetailDesc() != null) {
for (DimSchemaResp dimensionDesc : entityDesc.getEntityInternalDetailDesc().getDimensionList()) { if (Objects.nonNull(chaConfigRichDesc) && Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig())
DataInfo mainEntityDimension = new DataInfo(); && Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig())) {
mainEntityDimension.setItemId(dimensionDesc.getId().intValue()); ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig();
mainEntityDimension.setName(dimensionDesc.getName()); if(!CollectionUtils.isEmpty(chatDefaultConfig.getDimensions())){
mainEntityDimension.setBizName(dimensionDesc.getBizName()); for (SchemaItem dimensionDesc : chatDefaultConfig.getDimensions()) {
dimensions.add(mainEntityDimension); DataInfo mainEntityDimension = new DataInfo();
mainEntityDimension.setItemId(dimensionDesc.getId().intValue());
mainEntityDimension.setName(dimensionDesc.getName());
mainEntityDimension.setBizName(dimensionDesc.getBizName());
dimensions.add(mainEntityDimension);
}
entityInfo.setDimensions(dimensions);
} }
entityInfo.setDimensions(dimensions);
for (MetricSchemaResp metricDesc : entityDesc.getEntityInternalDetailDesc().getMetricList()) { if(!CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())){
DataInfo dataInfo = new DataInfo(); for (SchemaItem metricDesc : chatDefaultConfig.getMetrics()) {
dataInfo.setName(metricDesc.getName()); DataInfo dataInfo = new DataInfo();
dataInfo.setBizName(metricDesc.getBizName()); dataInfo.setName(metricDesc.getName());
dataInfo.setItemId(metricDesc.getId().intValue()); dataInfo.setBizName(metricDesc.getBizName());
metrics.add(dataInfo); dataInfo.setItemId(metricDesc.getId().intValue());
metrics.add(dataInfo);
}
entityInfo.setMetrics(metrics);
} }
entityInfo.setMetrics(metrics);
} }
} }
return entityInfo; return entityInfo;

View File

@@ -14,6 +14,7 @@ import com.tencent.supersonic.chat.domain.service.QueryService;
import com.tencent.supersonic.chat.domain.service.ChatService; import com.tencent.supersonic.chat.domain.service.ChatService;
import com.tencent.supersonic.chat.domain.utils.ComponentFactory; import com.tencent.supersonic.chat.domain.utils.ComponentFactory;
import com.tencent.supersonic.chat.domain.utils.SchemaInfoConverter; import com.tencent.supersonic.chat.domain.utils.SchemaInfoConverter;
import com.tencent.supersonic.common.util.json.JsonUtil;
import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp; import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -50,7 +51,6 @@ public class QueryServiceImpl implements QueryService {
log.info("semanticParser processing:[{}]", semanticParser.getClass().getName()); log.info("semanticParser processing:[{}]", semanticParser.getClass().getName());
semanticParser.parse(queryCtx, chatCtx); semanticParser.parse(queryCtx, chatCtx);
} }
if (queryCtx.getCandidateQueries().size() > 0) { if (queryCtx.getCandidateQueries().size() > 0) {
log.info("pick before [{}]", queryCtx.getCandidateQueries().stream().collect( log.info("pick before [{}]", queryCtx.getCandidateQueries().stream().collect(
Collectors.toList())); Collectors.toList()));

View File

@@ -29,7 +29,7 @@ public class RecommendServiceImpl implements RecommendService {
} }
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo( DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(
Long.valueOf(domainId)); Long.valueOf(domainId), true);
List<RecommendResponse.Item> dimensions = domainSchemaDesc.getDimensions().stream().map(dimSchemaDesc -> { List<RecommendResponse.Item> dimensions = domainSchemaDesc.getDimensions().stream().map(dimSchemaDesc -> {
RecommendResponse.Item item = new RecommendResponse.Item(); RecommendResponse.Item item = new RecommendResponse.Item();

View File

@@ -2,6 +2,8 @@ package com.tencent.supersonic.chat.application;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.hankcs.hanlp.seg.common.Term; import com.hankcs.hanlp.seg.common.Term;
import com.tencent.supersonic.chat.api.pojo.Filter;
import com.tencent.supersonic.chat.api.pojo.QueryFilter;
import com.tencent.supersonic.chat.api.pojo.SchemaElementType; import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
import com.tencent.supersonic.chat.api.request.QueryContextReq; import com.tencent.supersonic.chat.api.request.QueryContextReq;
import com.tencent.supersonic.chat.application.knowledge.NatureHelper; import com.tencent.supersonic.chat.application.knowledge.NatureHelper;
@@ -64,8 +66,7 @@ public class SearchServiceImpl implements SearchService {
List<ItemDO> metricsDb = domainInfosDb.getMetrics(); List<ItemDO> metricsDb = domainInfosDb.getMetrics();
final Map<Integer, String> domainToName = domainInfosDb.getDomainToName(); final Map<Integer, String> domainToName = domainInfosDb.getDomainToName();
// 2.detect by segment // 2.detect by segment
List<Term> originals = HanlpHelper.getSegment().seg(queryText.toLowerCase()).stream() List<Term> originals = HanlpHelper.getTerms(queryText);
.collect(Collectors.toList());
Map<MatchText, List<MapResult>> regTextMap = searchMatchStrategy.match(queryText, originals, Map<MatchText, List<MapResult>> regTextMap = searchMatchStrategy.match(queryText, originals,
queryCtx.getDomainId()); queryCtx.getDomainId());
regTextMap.entrySet().stream().forEach(m -> HanlpHelper.transLetterOriginal(m.getValue())); regTextMap.entrySet().stream().forEach(m -> HanlpHelper.transLetterOriginal(m.getValue()));
@@ -101,7 +102,7 @@ public class SearchServiceImpl implements SearchService {
for (Map.Entry<String, String> natureToNameEntry : natureToNameMap.entrySet()) { for (Map.Entry<String, String> natureToNameEntry : natureToNameMap.entrySet()) {
searchDimensionValue(metricsDb, domainToName, domainStat.getMetricDomainCount(), searchResults, searchDimensionValue(metricsDb, domainToName, domainStat.getMetricDomainCount(), searchResults,
existMetricAndDimension, matchText, natureToNameMap, natureToNameEntry); existMetricAndDimension, matchText, natureToNameMap, natureToNameEntry, queryCtx.getQueryFilter());
} }
return searchResults.stream().limit(RESULT_SIZE).collect(Collectors.toList()); return searchResults.stream().limit(RESULT_SIZE).collect(Collectors.toList());
} }
@@ -140,13 +141,14 @@ public class SearchServiceImpl implements SearchService {
} }
private void searchDimensionValue(List<ItemDO> metricsDb, private void searchDimensionValue(List<ItemDO> metricsDb,
Map<Integer, String> domainToName, Map<Integer, String> domainToName,
long metricDomainCount, long metricDomainCount,
Set<SearchResult> searchResults, Set<SearchResult> searchResults,
boolean existMetricAndDimension, boolean existMetricAndDimension,
MatchText matchText, MatchText matchText,
Map<String, String> natureToNameMap, Map<String, String> natureToNameMap,
Map.Entry<String, String> natureToNameEntry) { Map.Entry<String, String> natureToNameEntry,
QueryFilter queryFilter) {
String nature = natureToNameEntry.getKey(); String nature = natureToNameEntry.getKey();
String wordName = natureToNameEntry.getValue(); String wordName = natureToNameEntry.getValue();
@@ -158,6 +160,9 @@ public class SearchServiceImpl implements SearchService {
} }
// If there are no metric/dimension, complete the metric information // If there are no metric/dimension, complete the metric information
if (metricDomainCount <= 0 && !existMetricAndDimension) { if (metricDomainCount <= 0 && !existMetricAndDimension) {
if (filterByQueryFilter(matchText.getRegText(), queryFilter)) {
return;
}
searchResults.add( searchResults.add(
new SearchResult(matchText.getRegText() + wordName, wordName, domainToName.get(domain), domain, new SearchResult(matchText.getRegText() + wordName, wordName, domainToName.get(domain), domain,
schemaElementType)); schemaElementType));
@@ -167,7 +172,6 @@ public class SearchServiceImpl implements SearchService {
} }
List<String> metrics = filerMetricsByDomain(metricsDb, domain).stream().limit(metricSize).collect( List<String> metrics = filerMetricsByDomain(metricsDb, domain).stream().limit(metricSize).collect(
Collectors.toList()); Collectors.toList());
;
for (String metric : metrics) { for (String metric : metrics) {
String subRecommend = matchText.getRegText() + wordName + NatureType.SPACE + metric; String subRecommend = matchText.getRegText() + wordName + NatureType.SPACE + metric;
searchResults.add( searchResults.add(
@@ -181,6 +185,19 @@ public class SearchServiceImpl implements SearchService {
} }
} }
private boolean filterByQueryFilter(String regText, QueryFilter queryFilter) {
if (queryFilter == null || CollectionUtils.isEmpty(queryFilter.getFilters())) {
return false;
}
List<Filter> filters = queryFilter.getFilters();
for (Filter filter : filters) {
if (regText.equalsIgnoreCase(String.valueOf(filter.getValue()))) {
return false;
}
}
return true;
}
protected List<String> filerMetricsByDomain(List<ItemDO> metricsDb, Integer domain) { protected List<String> filerMetricsByDomain(List<ItemDO> metricsDb, Integer domain) {
if (CollectionUtils.isEmpty(metricsDb)) { if (CollectionUtils.isEmpty(metricsDb)) {
return Lists.newArrayList(); return Lists.newArrayList();

View File

@@ -31,8 +31,7 @@ public class DatabaseSchemaMapper implements SchemaMapper {
log.debug("before db mapper,mapInfo:{}", queryContext.getMapInfo()); log.debug("before db mapper,mapInfo:{}", queryContext.getMapInfo());
List<Term> terms = HanlpHelper.getSegment().seg(queryContext.getQueryText().toLowerCase()).stream() List<Term> terms = HanlpHelper.getTerms(queryContext.getQueryText());
.collect(Collectors.toList());
WordNatureService wordNatureService = ContextUtils.getBean(WordNatureService.class); WordNatureService wordNatureService = ContextUtils.getBean(WordNatureService.class);

View File

@@ -30,8 +30,7 @@ public class HanlpSchemaMapper implements SchemaMapper {
@Override @Override
public void map(QueryContextReq queryContext) { public void map(QueryContextReq queryContext) {
List<Term> terms = HanlpHelper.getSegment().seg(queryContext.getQueryText().toLowerCase()).stream() List<Term> terms = HanlpHelper.getTerms(queryContext.getQueryText());
.collect(Collectors.toList());
terms.forEach( terms.forEach(
item -> log.info("word:{},nature:{},frequency:{}", item.word, item.nature.toString(), item -> log.info("word:{},nature:{},frequency:{}", item.word, item.nature.toString(),
@@ -56,6 +55,8 @@ public class HanlpSchemaMapper implements SchemaMapper {
convertTermsToSchemaMapInfo(matches, queryContext.getMapInfo(), terms); convertTermsToSchemaMapInfo(matches, queryContext.getMapInfo(), terms);
} }
private void convertTermsToSchemaMapInfo(List<MapResult> mapResults, SchemaMapInfo schemaMap, List<Term> terms) { private void convertTermsToSchemaMapInfo(List<MapResult> mapResults, SchemaMapInfo schemaMap, List<Term> terms) {
if (CollectionUtils.isEmpty(mapResults)) { if (CollectionUtils.isEmpty(mapResults)) {
return; return;

View File

@@ -4,9 +4,12 @@ import com.google.common.collect.Lists;
import com.tencent.supersonic.chat.api.component.SchemaMapper; import com.tencent.supersonic.chat.api.component.SchemaMapper;
import com.tencent.supersonic.chat.api.pojo.*; import com.tencent.supersonic.chat.api.pojo.*;
import com.tencent.supersonic.chat.api.request.QueryContextReq; import com.tencent.supersonic.chat.api.request.QueryContextReq;
import com.tencent.supersonic.common.constant.Constants;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@@ -25,6 +28,7 @@ public class QueryFilterMapper implements SchemaMapper {
QueryFilter queryFilter = queryContext.getQueryFilter(); QueryFilter queryFilter = queryContext.getQueryFilter();
SchemaMapInfo schemaMapInfo = queryContext.getMapInfo(); SchemaMapInfo schemaMapInfo = queryContext.getMapInfo();
List<SchemaElementMatch> schemaElementMatches = schemaMapInfo.getMatchedElements(domainId); List<SchemaElementMatch> schemaElementMatches = schemaMapInfo.getMatchedElements(domainId);
clearOtherSchemaElementMatch(domainId, schemaMapInfo);
convertFilterToSchemaMapInfo(queryFilter.getFilters(), schemaElementMatches); convertFilterToSchemaMapInfo(queryFilter.getFilters(), schemaElementMatches);
} }
@@ -33,6 +37,7 @@ public class QueryFilterMapper implements SchemaMapper {
if (CollectionUtils.isEmpty(schemaElementMatches)) { if (CollectionUtils.isEmpty(schemaElementMatches)) {
schemaElementMatches = Lists.newArrayList(); schemaElementMatches = Lists.newArrayList();
} }
List<String> words = schemaElementMatches.stream().map(SchemaElementMatch::getWord).collect(Collectors.toList());
for (Filter filter : filters) { for (Filter filter : filters) {
SchemaElementMatch schemaElementMatch = SchemaElementMatch.builder() SchemaElementMatch schemaElementMatch = SchemaElementMatch.builder()
.elementType(SchemaElementType.VALUE) .elementType(SchemaElementType.VALUE)
@@ -40,11 +45,22 @@ public class QueryFilterMapper implements SchemaMapper {
.frequency(FREQUENCY) .frequency(FREQUENCY)
.word(String.valueOf(filter.getValue())) .word(String.valueOf(filter.getValue()))
.similarity(SIMILARITY) .similarity(SIMILARITY)
.detectWord(filter.getName()) .detectWord(Constants.EMPTY)
.build(); .build();
if (words.contains(schemaElementMatch.getWord())) {
continue;
}
schemaElementMatches.add(schemaElementMatch); schemaElementMatches.add(schemaElementMatch);
} }
log.info("schemaElementMatches after queryFilerMapper:{}", schemaElementMatches); log.info("schemaElementMatches after queryFilerMapper:{}", schemaElementMatches);
} }
private void clearOtherSchemaElementMatch(Integer domainId, SchemaMapInfo schemaMapInfo) {
for (Map.Entry<Integer, List<SchemaElementMatch>> entry : schemaMapInfo.getDomainElementMatches().entrySet()) {
if (!entry.getKey().equals(domainId)) {
entry.getValue().clear();
}
}
}
} }

View File

@@ -2,24 +2,28 @@ package com.tencent.supersonic.chat.application.parser;
import com.tencent.supersonic.chat.api.component.SemanticLayer; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.api.component.SemanticParser; import com.tencent.supersonic.chat.api.component.SemanticParser;
import com.tencent.supersonic.chat.api.component.SemanticQuery; import com.tencent.supersonic.chat.api.pojo.ChatContext;
import com.tencent.supersonic.chat.api.pojo.*; import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
import com.tencent.supersonic.chat.api.pojo.SchemaMapInfo;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.api.request.QueryContextReq; import com.tencent.supersonic.chat.api.request.QueryContextReq;
import com.tencent.supersonic.chat.application.query.*; import com.tencent.supersonic.chat.application.query.EntitySemanticQuery;
import com.tencent.supersonic.chat.application.query.MetricSemanticQuery;
import com.tencent.supersonic.chat.application.query.RuleSemanticQuery;
import com.tencent.supersonic.chat.application.query.RuleSemanticQueryManager;
import com.tencent.supersonic.chat.domain.pojo.chat.DomainInfos; import com.tencent.supersonic.chat.domain.pojo.chat.DomainInfos;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
import com.tencent.supersonic.chat.domain.utils.*; import com.tencent.supersonic.chat.domain.service.ConfigService;
import com.tencent.supersonic.common.pojo.SchemaItem; import com.tencent.supersonic.chat.domain.utils.ComponentFactory;
import com.tencent.supersonic.chat.domain.utils.ContextHelper;
import com.tencent.supersonic.chat.domain.utils.DefaultMetricUtils;
import com.tencent.supersonic.chat.domain.utils.SchemaInfoConverter;
import com.tencent.supersonic.common.util.context.ContextUtils; import com.tencent.supersonic.common.util.context.ContextUtils;
import java.util.*; import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -37,10 +41,15 @@ public class DomainSemanticParser implements SemanticParser {
// iterate all schemaElementMatches to resolve semantic query // iterate all schemaElementMatches to resolve semantic query
for (Integer domainId : mapInfo.getMatchedDomains()) { for (Integer domainId : mapInfo.getMatchedDomains()) {
List<SchemaElementMatch> elementMatches = mapInfo.getMatchedElements(domainId); List<SchemaElementMatch> elementMatches = mapInfo.getMatchedElements(domainId);
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = resolveQuery(elementMatches, queryContext); List<RuleSemanticQuery> queries = resolveQuery(elementMatches, queryContext);
for (Map.Entry<RuleSemanticQuery, List<SchemaElementMatch>> match : queryMatches.entrySet()) { for (RuleSemanticQuery query : queries) {
if (useBlackItem(query, domainId)) {
log.info("useBlackItem, skip query:{}", query);
continue;
}
addCandidateQuery(queryContext, chatContext, domainId.longValue(), addCandidateQuery(queryContext, chatContext, domainId.longValue(),
domainToName.get(domainId), match.getKey(), match.getValue()); domainToName.get(domainId), query);
} }
} }
@@ -50,27 +59,95 @@ public class DomainSemanticParser implements SemanticParser {
Integer chatDomainId = Integer.valueOf(chatContext.getParseInfo().getDomainId().intValue()); Integer chatDomainId = Integer.valueOf(chatContext.getParseInfo().getDomainId().intValue());
if (mapInfo.getMatchedDomains().contains(chatDomainId)) { if (mapInfo.getMatchedDomains().contains(chatDomainId)) {
List<SchemaElementMatch> elementMatches = mapInfo.getMatchedElements(chatDomainId); List<SchemaElementMatch> elementMatches = mapInfo.getMatchedElements(chatDomainId);
detectionContext(chatContext);
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = tryParseByContext(elementMatches, List<RuleSemanticQuery> queries = tryParseByContext(elementMatches, chatContext, queryContext);
chatContext, queryContext); for (RuleSemanticQuery query : queries) {
for (Map.Entry<RuleSemanticQuery, List<SchemaElementMatch>> match : queryMatches.entrySet()) {
addCandidateQuery(queryContext, chatContext, chatDomainId.longValue(), addCandidateQuery(queryContext, chatContext, chatDomainId.longValue(),
domainToName.get(chatDomainId), match.getKey(), match.getValue()); domainToName.get(chatDomainId), query);
} }
} }
} }
} }
} }
private boolean useBlackItem(RuleSemanticQuery query, Integer domainId) {
if (Objects.isNull(domainId)) {
return false;
}
ConfigService configService = ContextUtils.getBean(ConfigService.class);
ChatConfigResp chatConfigResp = configService.fetchConfigByDomainId(domainId.longValue());
if (Objects.nonNull(chatConfigResp) && Objects.nonNull(query) && Objects.nonNull(query.getParseInfo())) {
List<SchemaElementMatch> elementMatches = query.getParseInfo().getElementMatches();
if (!CollectionUtils.isEmpty(elementMatches)) {
return useBlackItemInternal(elementMatches, chatConfigResp, query);
}
}
return false;
}
private boolean useBlackItemInternal(List<SchemaElementMatch> elementMatches, ChatConfigResp chatConfigResp, RuleSemanticQuery query) {
if (Objects.isNull(chatConfigResp)) {
return false;
}
List<Long> blackDimIdList = new ArrayList<>();
List<Long> blackMetricIdList = new ArrayList<>();
if (query instanceof EntitySemanticQuery
&& Objects.nonNull(chatConfigResp.getChatDetailConfig())
&& Objects.nonNull(chatConfigResp.getChatDetailConfig().getVisibility())) {
log.info("useBlackItem, handle EntitySemanticQuery blackList logic");
blackDimIdList = chatConfigResp.getChatDetailConfig().getVisibility().getBlackDimIdList();
blackMetricIdList = chatConfigResp.getChatDetailConfig().getVisibility().getBlackMetricIdList();
}
if (query instanceof MetricSemanticQuery
&& Objects.nonNull(chatConfigResp.getChatAggConfig())
&& Objects.nonNull(chatConfigResp.getChatAggConfig().getVisibility())) {
log.info("useBlackItem, handle MetricSemanticQuery blackList logic");
blackDimIdList = chatConfigResp.getChatAggConfig().getVisibility().getBlackDimIdList();
blackMetricIdList = chatConfigResp.getChatAggConfig().getVisibility().getBlackMetricIdList();
}
return useBlackItemWithElementMatches(elementMatches, blackDimIdList, blackMetricIdList);
}
private boolean useBlackItemWithElementMatches(List<SchemaElementMatch> elementMatches, List<Long> blackDimIdList, List<Long> blackMetricIdList) {
Set<Long> dimIds = elementMatches.stream()
.filter(element -> SchemaElementType.VALUE.equals(element.getElementType()) || SchemaElementType.DIMENSION.equals(element.getElementType()))
.map(element -> Long.valueOf(element.getElementID())).collect(Collectors.toSet());
Set<Long> metricIds = elementMatches.stream()
.filter(element -> SchemaElementType.METRIC.equals(element.getElementType()))
.map(element -> Long.valueOf(element.getElementID())).collect(Collectors.toSet());
return useBlackItemWithIds(dimIds, metricIds, blackDimIdList, blackMetricIdList);
}
private boolean useBlackItemWithIds(Set<Long> dimIds, Set<Long> metricIds, List<Long> blackDimIdList, List<Long> blackMetricIdList) {
if (!CollectionUtils.isEmpty(blackDimIdList) && !CollectionUtils.isEmpty(dimIds)) {
if (blackDimIdList.stream().anyMatch(dimIds::contains)) {
log.info("useBlackItem, blackDimIdList:{}", blackDimIdList.stream().filter(dimIds::contains).collect(Collectors.toList()));
return true;
}
}
if (!CollectionUtils.isEmpty(blackMetricIdList) && !CollectionUtils.isEmpty(metricIds)) {
if (blackMetricIdList.stream().anyMatch(metricIds::contains)) {
log.info("useBlackItem, blackMetricIdList:{}", blackMetricIdList.stream().filter(metricIds::contains).collect(Collectors.toList()));
return true;
}
}
return false;
}
private void addCandidateQuery(QueryContextReq queryContext, ChatContext chatContext, private void addCandidateQuery(QueryContextReq queryContext, ChatContext chatContext,
Long domainId, String domainName, Long domainId, String domainName, RuleSemanticQuery semanticQuery) {
RuleSemanticQuery semanticQuery, List<SchemaElementMatch> elementMatches) {
if (semanticQuery != null) { if (semanticQuery != null) {
fillParseInfo(semanticQuery, domainId, domainName, elementMatches); DefaultMetricUtils defaultMetricUtils = ContextUtils.getBean(DefaultMetricUtils.class);
// inherit from context defaultMetricUtils.fillParseInfo(semanticQuery, domainId, domainName);
inheritContext(semanticQuery, chatContext); inheritContext(semanticQuery, chatContext);
// default metric, date, dimension defaultMetricUtils.fillDefaultMetric(semanticQuery.getParseInfo(), queryContext, chatContext);
injectDefaultMetric(semanticQuery, queryContext, chatContext);
queryContext.getCandidateQueries().add(semanticQuery); queryContext.getCandidateQueries().add(semanticQuery);
} }
} }
@@ -84,38 +161,15 @@ public class DomainSemanticParser implements SemanticParser {
} }
} }
protected void injectDefaultMetric(RuleSemanticQuery semanticQuery, QueryContextReq queryContext,
ChatContext chatContext) {
DefaultMetricUtils defaultMetricUtils = ContextUtils.getBean(DefaultMetricUtils.class);
defaultMetricUtils.injectDefaultMetric(semanticQuery.getParseInfo(), queryContext, chatContext);
}
/** /**
* get the chatContext for the tryParseByContext * try to add ChatContext to SchemaMatch and look if match QueryMode
*
* @param chatContext
*/
protected void detectionContext(ChatContext chatContext) {
if (chatContext.getParseInfo() != null) {
SemanticParseInfo semanticParseInfo = chatContext.getParseInfo();
if (semanticParseInfo.getQueryMode().equals(EntityDetail.QUERY_MODE)) {
// EntityDetail model will unset some items
semanticParseInfo.setDateInfo(null);
semanticParseInfo.setMetrics(new HashSet<>());
semanticParseInfo.setDimensions(new HashSet<>());
}
}
}
/**
* try to add ChatContext to SchemaElementMatch and look if match QueryMode
* *
* @param elementMatches * @param elementMatches
* @param chatCtx * @param chatCtx
* @return * @return
*/ */
private Map<RuleSemanticQuery, List<SchemaElementMatch>> tryParseByContext(List<SchemaElementMatch> elementMatches, private List<RuleSemanticQuery> tryParseByContext(List<SchemaElementMatch> elementMatches,
ChatContext chatCtx, QueryContextReq queryCtx) { ChatContext chatCtx, QueryContextReq queryCtx) {
if (chatCtx.getParseInfo() != null && chatCtx.getParseInfo().getEntity() > 0) { if (chatCtx.getParseInfo() != null && chatCtx.getParseInfo().getEntity() > 0) {
Long entityCount = elementMatches.stream().filter(i -> SchemaElementType.ENTITY.equals(i.getElementType())) Long entityCount = elementMatches.stream().filter(i -> SchemaElementType.ENTITY.equals(i.getElementType()))
.count(); .count();
@@ -125,15 +179,14 @@ public class DomainSemanticParser implements SemanticParser {
// try entity parse // try entity parse
SchemaElementMatch entityElementMatch = SchemaElementMatch.builder() SchemaElementMatch entityElementMatch = SchemaElementMatch.builder()
.elementType(SchemaElementType.ENTITY).build(); .elementType(SchemaElementType.ENTITY).build();
List<SchemaElementMatch> newSchemaElementMatch = new ArrayList<>(); List<SchemaElementMatch> newSchemaMatches = new ArrayList<>();
if (!CollectionUtils.isEmpty(elementMatches)) { if (!CollectionUtils.isEmpty(elementMatches)) {
newSchemaElementMatch.addAll(elementMatches); newSchemaMatches.addAll(elementMatches);
} }
newSchemaElementMatch.add(entityElementMatch); newSchemaMatches.add(entityElementMatch);
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = doParseByContext(newSchemaElementMatch, List<RuleSemanticQuery> queries = doParseByContext(newSchemaMatches, chatCtx, queryCtx);
chatCtx, queryCtx); if (queries.size() > 0) {
if (queryMatches.size() > 0) { return queries;
return queryMatches;
} }
} }
} }
@@ -141,8 +194,8 @@ public class DomainSemanticParser implements SemanticParser {
} }
private Map<RuleSemanticQuery, List<SchemaElementMatch>> doParseByContext(List<SchemaElementMatch> elementMatches, private List<RuleSemanticQuery> doParseByContext(List<SchemaElementMatch> elementMatches,
ChatContext chatCtx, QueryContextReq queryCtx) { ChatContext chatCtx, QueryContextReq queryContext) {
SemanticParseInfo contextSemanticParse = chatCtx.getParseInfo(); SemanticParseInfo contextSemanticParse = chatCtx.getParseInfo();
if (contextSemanticParse != null) { if (contextSemanticParse != null) {
List<SchemaElementMatch> newElementMatches = new ArrayList<>(); List<SchemaElementMatch> newElementMatches = new ArrayList<>();
@@ -162,123 +215,36 @@ public class DomainSemanticParser implements SemanticParser {
trySchemaElementTypes.add(new ArrayList<>(Arrays.asList(SchemaElementType.VALUE))); trySchemaElementTypes.add(new ArrayList<>(Arrays.asList(SchemaElementType.VALUE)));
trySchemaElementTypes.add(new ArrayList<>(Arrays.asList(SchemaElementType.DIMENSION))); trySchemaElementTypes.add(new ArrayList<>(Arrays.asList(SchemaElementType.DIMENSION)));
for (List<SchemaElementType> schemaElementTypes : trySchemaElementTypes) { for (List<SchemaElementType> schemaTypes : trySchemaElementTypes) {
newElementMatches.clear(); newElementMatches.clear();
if (!CollectionUtils.isEmpty(elementMatches)) { if (!CollectionUtils.isEmpty(elementMatches)) {
newElementMatches.addAll(elementMatches); newElementMatches.addAll(elementMatches);
} }
ContextHelper.mergeContextSchemaElementMatch(newElementMatches, elementMatches, schemaElementTypes, ContextHelper.mergeContextSchemaElementMatch(newElementMatches, elementMatches, schemaTypes,
contextSemanticParse); contextSemanticParse);
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = resolveQuery(newElementMatches, List<RuleSemanticQuery> queries = resolveQuery(newElementMatches, queryContext);
queryCtx); if (queries.size() > 0) {
if (queryMatches.size() > 0) { return queries;
return queryMatches;
} }
} }
} }
return new HashMap<>(); return new ArrayList<>();
} }
private Map<RuleSemanticQuery, List<SchemaElementMatch>> resolveQuery(List<SchemaElementMatch> elementMatches, private List<RuleSemanticQuery> resolveQuery(List<SchemaElementMatch> candidateElementMatches,
QueryContextReq queryCtx) { QueryContextReq queryContext) {
Map<RuleSemanticQuery, List<SchemaElementMatch>> matchMap = new HashMap<>(); List<RuleSemanticQuery> matchedQueries = new ArrayList<>();
for (RuleSemanticQuery semanticQuery : RuleSemanticQueryManager.getSemanticQueries()) { for (RuleSemanticQuery semanticQuery : RuleSemanticQueryManager.getSemanticQueries()) {
List<SchemaElementMatch> matches = semanticQuery.match(elementMatches, queryCtx); List<SchemaElementMatch> matches = semanticQuery.match(candidateElementMatches, queryContext);
if (matches.size() > 0) { if (matches.size() > 0) {
log.info("resolve match [{}:{}] ", semanticQuery.getQueryMode(), matches.size()); log.info("resolve match [{}:{}] ", semanticQuery.getQueryMode(), matches.size());
matchMap.put(RuleSemanticQueryManager.create(semanticQuery.getQueryMode()), matches); RuleSemanticQuery query = RuleSemanticQueryManager.create(semanticQuery.getQueryMode());
query.getParseInfo().getElementMatches().addAll(matches);
matchedQueries.add(query);
} }
} }
return matchMap; return matchedQueries;
} }
}
public void fillParseInfo(SemanticQuery query, Long domainId, String domainName,
List<SchemaElementMatch> elementMatches) {
SemanticParseInfo parseInfo = query.getParseInfo();
parseInfo.setDomainId(domainId);
parseInfo.setDomainName(domainName);
parseInfo.setQueryMode(query.getQueryMode());
parseInfo.getElementMatches().addAll(elementMatches);
DefaultSemanticInternalUtils defaultSemanticUtils = ContextUtils.getBean(DefaultSemanticInternalUtils.class);
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(parseInfo.getDomainId());
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(parseInfo.getDomainId());
Map<Long, DimSchemaResp> dimensionDescMap = domainSchemaDesc.getDimensions().stream()
.collect(Collectors.toMap(DimSchemaResp::getId, Function.identity()));
Map<Long, MetricSchemaResp> metricDescMap = domainSchemaDesc.getMetrics().stream()
.collect(Collectors.toMap(MetricSchemaResp::getId, Function.identity()));
Map<Long, List<SchemaElementMatch>> dim2Values = new HashMap<>();
for (SchemaElementMatch schemaElementMatch : elementMatches) {
Long elementID = Long.valueOf(schemaElementMatch.getElementID());
switch (schemaElementMatch.getElementType()) {
case ID:
case VALUE:
if (dimensionDescMap.containsKey(elementID)) {
if (dim2Values.containsKey(elementID)) {
dim2Values.get(elementID).add(schemaElementMatch);
} else {
dim2Values.put(elementID, new ArrayList<>(Arrays.asList(schemaElementMatch)));
}
}
break;
case DIMENSION:
DimSchemaResp dimensionDesc = dimensionDescMap.get(elementID);
if (dimensionDesc != null) {
SchemaItem dimensionParseInfo = new SchemaItem();
dimensionParseInfo.setBizName(dimensionDesc.getBizName());
dimensionParseInfo.setName(dimensionDesc.getName());
dimensionParseInfo.setId(dimensionDesc.getId());
parseInfo.getDimensions().add(dimensionParseInfo);
}
break;
case METRIC:
MetricSchemaResp metricDesc = metricDescMap.get(elementID);
if (metricDesc != null) {
SchemaItem metricItem = new SchemaItem();
metricItem.setBizName(metricDesc.getBizName());
metricItem.setName(metricDesc.getName());
metricItem.setId(metricDesc.getId());
metricItem.setCreatedAt(null);
metricItem.setUpdatedAt(null);
parseInfo.getMetrics().add(metricItem);
}
break;
default:
}
}
if (!dim2Values.isEmpty()) {
for (Map.Entry<Long, List<SchemaElementMatch>> entry : dim2Values.entrySet()) {
DimSchemaResp dimensionDesc = dimensionDescMap.get(entry.getKey());
if (entry.getValue().size() == 1) {
SchemaElementMatch schemaElementMatch = entry.getValue().get(0);
Filter dimensionFilter = new Filter();
dimensionFilter.setValue(schemaElementMatch.getWord());
dimensionFilter.setBizName(dimensionDesc.getBizName());
dimensionFilter.setName(dimensionDesc.getName());
dimensionFilter.setOperator(FilterOperatorEnum.EQUALS);
dimensionFilter.setElementID(Long.valueOf(schemaElementMatch.getElementID()));
parseInfo.getDimensionFilters().add(dimensionFilter);
ContextHelper.setEntityId(entry.getKey(), schemaElementMatch.getWord(), chaConfigRichDesc,
parseInfo);
} else {
Filter dimensionFilter = new Filter();
List<String> vals = new ArrayList<>();
entry.getValue().stream().forEach(i -> vals.add(i.getWord()));
dimensionFilter.setValue(vals);
dimensionFilter.setBizName(dimensionDesc.getBizName());
dimensionFilter.setName(dimensionDesc.getName());
dimensionFilter.setOperator(FilterOperatorEnum.IN);
dimensionFilter.setElementID(entry.getKey());
parseInfo.getDimensionFilters().add(dimensionFilter);
}
}
}
}
}

View File

@@ -20,6 +20,7 @@ import com.tencent.supersonic.chat.domain.utils.SemanticSatisfactionChecker;
import com.tencent.supersonic.common.nlp.ItemDO; import com.tencent.supersonic.common.nlp.ItemDO;
import com.tencent.supersonic.common.util.context.ContextUtils; import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.common.util.json.JsonUtil; import com.tencent.supersonic.common.util.json.JsonUtil;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -28,6 +29,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
@@ -40,90 +42,100 @@ import org.springframework.web.client.RestTemplate;
@Slf4j @Slf4j
public class LLMSemanticParser implements SemanticParser { public class LLMSemanticParser implements SemanticParser {
private DslToSemanticInfo dslToSemanticInfo = new DslToSemanticInfo();
@Override @Override
public void parse(QueryContextReq queryContext, ChatContext chatCtx) { public void parse(QueryContextReq queryContext, ChatContext chatCtx) {
String queryText = queryContext.getQueryText();
if (SemanticSatisfactionChecker.check(queryContext)) { if (SemanticSatisfactionChecker.check(queryContext)) {
log.info("There is no need parse by llm , queryText:{}", queryContext.getQueryText()); log.info("There is no need parse by llm , queryText:{}", queryText);
return; return;
} }
Integer domainId = getDomainId(queryContext, chatCtx); try {
LLMResp llmResp = requestLLM(queryContext, domainId); Integer domainId = getDomainId(queryContext, chatCtx);
if (Objects.isNull(llmResp)) { LLMResp llmResp = requestLLM(queryContext, domainId);
if (Objects.isNull(llmResp)) {
return;
}
LLMSemanticQuery semanticQuery = new LLMSemanticQuery();
SemanticParseInfo parseInfo = semanticQuery.getParseInfo();
String sql = convertToSql(llmResp, parseInfo, domainId);
parseInfo.setInfo(sql);
parseInfo.setDomainId(Long.valueOf(domainId));
parseInfo.setBonus(queryText.length() * 1.0);
parseInfo.setQueryMode(LLMSemanticQuery.QUERY_MODE);
queryContext.getCandidateQueries().add(semanticQuery);
return; return;
} catch (Exception e) {
log.error("llm parse error , skip the parser. error:", e);
} }
LLMSemanticQuery semanticQuery = new LLMSemanticQuery();
SemanticParseInfo parseInfo = semanticQuery.getParseInfo();
String sql = convertToSql(llmResp, parseInfo);
parseInfo.setDomainId(Long.valueOf(domainId));
parseInfo.setBonus(queryContext.getQueryText().length() * 1.0);
parseInfo.setQueryMode(LLMSemanticQuery.QUERY_MODE);
parseInfo.setInfo(sql);
queryContext.getCandidateQueries().add(semanticQuery);
return;
} }
protected String convertToSql(LLMResp llmResp, SemanticParseInfo parseInfo) { protected String convertToSql(LLMResp llmResp, SemanticParseInfo parseInfo, Integer domainId)
return DslToSemanticInfo.convert(parseInfo, llmResp); throws SqlParseException {
return dslToSemanticInfo.convert(parseInfo, llmResp, domainId);
} }
protected LLMResp requestLLM(QueryContextReq queryContext, Integer domainId) { protected LLMResp requestLLM(QueryContextReq queryContext, Integer domainId) {
try { final LLMConfig llmConfig = ContextUtils.getBean(LLMConfig.class);
final LLMConfig llmConfig = ContextUtils.getBean(LLMConfig.class);
DomainInfos domainInfos = ContextUtils.getBean(WordNatureService.class).getCache().getUnchecked(""); if (StringUtils.isEmpty(llmConfig.getUrl())) {
log.warn("llmConfig url is null, skip llm parser");
Map<Integer, String> domainIdToName = domainInfos.getDomains().stream() return null;
.collect(Collectors.toMap(ItemDO::getDomain, a -> a.getName(), (k1, k2) -> k1));
Map<Integer, String> itemIdToName = domainInfos.getDimensions().stream()
.filter(entry -> domainId.equals(entry.getDomain()))
.collect(Collectors.toMap(ItemDO::getItemId, ItemDO::getName, (value1, value2) -> value2));
String domainName = domainIdToName.get(domainId);
LLMReq llmReq = new LLMReq();
llmReq.setQueryText(queryContext.getQueryText());
List<SchemaElementMatch> matchedElements = queryContext.getMapInfo().getMatchedElements(domainId);
List<String> fieldNameList = matchedElements.stream()
.filter(schemaElementMatch ->
SchemaElementType.METRIC.equals(schemaElementMatch.getElementType()) ||
SchemaElementType.DIMENSION.equals(schemaElementMatch.getElementType()) ||
SchemaElementType.VALUE.equals(schemaElementMatch.getElementType()))
.map(schemaElementMatch -> {
if (!SchemaElementType.VALUE.equals(schemaElementMatch.getElementType())) {
return schemaElementMatch.getWord();
}
return itemIdToName.get(schemaElementMatch.getElementID());
})
.filter(name -> StringUtils.isNotEmpty(name) && !name.contains("%"))
.collect(Collectors.toList());
LLMSchema llmSchema = new LLMSchema();
llmSchema.setDomainName(domainName);
llmSchema.setFieldNameList(fieldNameList);
llmReq.setSchema(llmSchema);
log.info("domainId:{},llmReq:{}", domainId, llmReq);
String questUrl = llmConfig.getUrl() + llmConfig.getQueryToSqlPath();
RestTemplate restTemplate = ContextUtils.getBean(RestTemplate.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(JsonUtil.toString(llmReq), headers);
log.info("requestLLM request:{},entity:{}", questUrl, entity);
ResponseEntity<LLMResp> responseEntity = restTemplate.exchange(questUrl, HttpMethod.POST, entity,
LLMResp.class);
log.info("requestLLM result:{}", responseEntity);
return responseEntity.getBody();
} catch (Exception e) {
log.error("requestLLM error", e);
} }
return null;
DomainInfos domainInfos = ContextUtils.getBean(WordNatureService.class).getCache().getUnchecked("");
Map<Integer, String> domainIdToName = domainInfos.getDomains().stream()
.collect(Collectors.toMap(ItemDO::getDomain, a -> a.getName(), (k1, k2) -> k1));
Map<Integer, String> itemIdToName = domainInfos.getDimensions().stream()
.filter(entry -> domainId.equals(entry.getDomain()))
.collect(Collectors.toMap(ItemDO::getItemId, ItemDO::getName, (value1, value2) -> value2));
String domainName = domainIdToName.get(domainId);
LLMReq llmReq = new LLMReq();
llmReq.setQueryText(queryContext.getQueryText());
List<SchemaElementMatch> matchedElements = queryContext.getMapInfo().getMatchedElements(domainId);
Set<String> fieldNameList = matchedElements.stream()
.filter(schemaElementMatch ->
SchemaElementType.METRIC.equals(schemaElementMatch.getElementType()) ||
SchemaElementType.DIMENSION.equals(schemaElementMatch.getElementType()) ||
SchemaElementType.VALUE.equals(schemaElementMatch.getElementType()))
.map(schemaElementMatch -> {
if (!SchemaElementType.VALUE.equals(schemaElementMatch.getElementType())) {
return schemaElementMatch.getWord();
}
return itemIdToName.get(schemaElementMatch.getElementID());
})
.filter(name -> StringUtils.isNotEmpty(name) && !name.contains("%"))
.collect(Collectors.toSet());
LLMSchema llmSchema = new LLMSchema();
llmSchema.setDomainName(domainName);
llmSchema.setFieldNameList(new ArrayList<>(fieldNameList));
llmReq.setSchema(llmSchema);
log.info("requestLLM request, domainId:{},llmReq:{}", domainId, llmReq);
String questUrl = llmConfig.getUrl() + llmConfig.getQueryToSqlPath();
RestTemplate restTemplate = ContextUtils.getBean(RestTemplate.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(JsonUtil.toString(llmReq), headers);
ResponseEntity<LLMResp> responseEntity = restTemplate.exchange(questUrl, HttpMethod.POST, entity,
LLMResp.class);
log.info("requestLLM response, questUrl:{} \n entity:{} \n body:{}", questUrl, entity,
responseEntity.getBody());
return responseEntity.getBody();
} }
protected Integer getDomainId(QueryContextReq queryContext, ChatContext chatCtx) { protected Integer getDomainId(QueryContextReq queryContext, ChatContext chatCtx) {

View File

@@ -66,19 +66,18 @@ public class TimeSemanticParser implements SemanticParser {
DateConf info = new DateConf(); DateConf info = new DateConf();
String zhPeriod = m.group("zhPeriod"); String zhPeriod = m.group("zhPeriod");
int days; int days;
info.setPeriod(Constants.DAY);
switch (zhPeriod) { switch (zhPeriod) {
case "": case "":
days = 7; days = 7;
//info.setPeriod(Constants.WEEK); info.setPeriod(Constants.WEEK);
break; break;
case "": case "":
days = 30; days = 30;
//info.setPeriod(Constants.MONTH); info.setPeriod(Constants.MONTH);
break; break;
case "": case "":
days = 365; days = 365;
//info.setPeriod(Constants.YEAR); info.setPeriod(Constants.YEAR);
break; break;
default: default:
days = 1; days = 1;
@@ -92,7 +91,7 @@ public class TimeSemanticParser implements SemanticParser {
} }
info.setText(text); info.setText(text);
info.setStartDate(LocalDate.now().minusDays(days).toString()); info.setStartDate(LocalDate.now().minusDays(days).toString());
info.setUnit(days); info.setUnit(num);
//queryContext.getParseInfo().setDateInfo(info); //queryContext.getParseInfo().setDateInfo(info);
for (SemanticQuery query : queryContext.getCandidateQueries()) { for (SemanticQuery query : queryContext.getCandidateQueries()) {
if (query instanceof MetricSemanticQuery) { if (query instanceof MetricSemanticQuery) {

View File

@@ -1,31 +1,33 @@
package com.tencent.supersonic.chat.application.query; package com.tencent.supersonic.chat.application.query;
import static com.tencent.supersonic.chat.api.pojo.SchemaElementType.VALUE; import static com.tencent.supersonic.chat.api.pojo.SchemaElementType.*;
import static com.tencent.supersonic.chat.application.query.QueryMatchOption.RequireNumberType.AT_LEAST; import static com.tencent.supersonic.chat.application.query.QueryMatchOption.RequireNumberType.*;
import static com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption.REQUIRED; import static com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption.*;
import static com.tencent.supersonic.common.constant.Constants.DAY; import static com.tencent.supersonic.common.constant.Constants.DAY;
import com.tencent.supersonic.chat.api.pojo.ChatContext; import com.tencent.supersonic.chat.api.pojo.ChatContext;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo; import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatDefaultRichConfig;
import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo;
import com.tencent.supersonic.chat.domain.service.ConfigService;
import com.tencent.supersonic.chat.domain.utils.ContextHelper; import com.tencent.supersonic.chat.domain.utils.ContextHelper;
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
import com.tencent.supersonic.common.constant.Constants; import com.tencent.supersonic.common.constant.Constants;
import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.DateConf;
import com.tencent.supersonic.common.pojo.Order; import com.tencent.supersonic.common.pojo.Order;
import com.tencent.supersonic.common.pojo.SchemaItem; import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.common.util.context.ContextUtils; import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Slf4j @Slf4j
@Component @Component
@@ -34,11 +36,14 @@ public class EntityListFilter extends EntitySemanticQuery {
public static String QUERY_MODE = "ENTITY_LIST_FILTER"; public static String QUERY_MODE = "ENTITY_LIST_FILTER";
private static Long entityListLimit = 200L; private static Long entityListLimit = 200L;
public EntityListFilter() { public EntityListFilter() {
super(); super();
queryMatcher.addOption(VALUE, REQUIRED, AT_LEAST, 1); queryMatcher.addOption(VALUE, REQUIRED, AT_LEAST, 1)
.addOption(ENTITY, REQUIRED, AT_LEAST, 1);
} }
@Override @Override
public String getQueryMode() { public String getQueryMode() {
return QUERY_MODE; return QUERY_MODE;
@@ -67,33 +72,32 @@ public class EntityListFilter extends EntitySemanticQuery {
private void addEntityDetailAndOrderByMetric(SemanticParseInfo semanticParseInfo) { private void addEntityDetailAndOrderByMetric(SemanticParseInfo semanticParseInfo) {
if (semanticParseInfo.getDomainId() > 0L) { if (semanticParseInfo.getDomainId() > 0L) {
DefaultSemanticInternalUtils defaultSemanticUtils = ContextUtils.getBean( ConfigService configService = ContextUtils.getBean(ConfigService.class);
DefaultSemanticInternalUtils.class); ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(
semanticParseInfo.getDomainId()); semanticParseInfo.getDomainId());
if (chaConfigRichDesc != null) { if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null
//SemanticParseInfo semanticParseInfo = queryContext.getParseInfo(); && chaConfigRichDesc.getChatDetailRichConfig().getEntity() != null) {
// SemanticParseInfo semanticParseInfo = queryContext.getParseInfo();
// EntityRichInfo entity = chaConfigRichDesc.getChatDetailRichConfig().getEntity();
Set<SchemaItem> dimensions = new LinkedHashSet(); Set<SchemaItem> dimensions = new LinkedHashSet();
Set<String> primaryDimensions = this.addPrimaryDimension(chaConfigRichDesc.getEntity(), dimensions); // Set<String> primaryDimensions = this.addPrimaryDimension(entity, dimensions);
Set<SchemaItem> metrics = new LinkedHashSet(); Set<SchemaItem> metrics = new LinkedHashSet();
if (chaConfigRichDesc.getEntity() != null Set<Order> orders = new LinkedHashSet();
&& chaConfigRichDesc.getEntity().getEntityInternalDetailDesc() != null) { ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig();
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getMetricList().stream() if (chatDefaultConfig != null) {
.forEach((m) -> metrics.add(this.getMetric(m))); chatDefaultConfig.getMetrics().stream()
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getDimensionList().stream() .forEach(metric -> {
.filter((m) -> !primaryDimensions.contains(m.getBizName())) metrics.add(metric);
.forEach((m) -> dimensions.add(this.getDimension(m))); orders.add(new Order(metric.getBizName(), Constants.DESC_UPPER));
});
chatDefaultConfig.getDimensions().stream()
// .filter((m) -> !primaryDimensions.contains(m.getBizName()))
.forEach(dimension -> dimensions.add(dimension));
} }
semanticParseInfo.setDimensions(dimensions); semanticParseInfo.setDimensions(dimensions);
semanticParseInfo.setMetrics(metrics); semanticParseInfo.setMetrics(metrics);
Set<Order> orders = new LinkedHashSet();
if (chaConfigRichDesc.getEntity() != null
&& chaConfigRichDesc.getEntity().getEntityInternalDetailDesc() != null) {
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getMetricList().stream()
.forEach((metric) -> orders.add(new Order(metric.getBizName(), Constants.DESC_UPPER)));
}
semanticParseInfo.setOrders(orders); semanticParseInfo.setOrders(orders);
} }
} }
@@ -102,35 +106,18 @@ public class EntityListFilter extends EntitySemanticQuery {
private Set<String> addPrimaryDimension(EntityRichInfo entity, Set<SchemaItem> dimensions) { private Set<String> addPrimaryDimension(EntityRichInfo entity, Set<SchemaItem> dimensions) {
Set<String> primaryDimensions = new HashSet(); Set<String> primaryDimensions = new HashSet();
if (!Objects.isNull(entity) && !CollectionUtils.isEmpty(entity.getEntityIds())) { DimSchemaResp dimItem = entity.getDimItem();
entity.getEntityIds().stream().forEach((dimSchemaDesc) -> { if (Objects.nonNull(entity) && Objects.nonNull(dimItem)) {
SchemaItem dimension = new SchemaItem(); SchemaItem dimension = new SchemaItem();
BeanUtils.copyProperties(dimSchemaDesc, dimension); BeanUtils.copyProperties(dimItem, dimension);
dimensions.add(dimension); dimensions.add(dimension);
primaryDimensions.add(dimSchemaDesc.getBizName()); primaryDimensions.add(dimItem.getBizName());
});
return primaryDimensions; return primaryDimensions;
} else { } else {
return primaryDimensions; return primaryDimensions;
} }
} }
private SchemaItem getMetric(MetricSchemaResp metricSchemaDesc) {
SchemaItem queryMeta = new SchemaItem();
queryMeta.setId(metricSchemaDesc.getId());
queryMeta.setBizName(metricSchemaDesc.getBizName());
queryMeta.setName(metricSchemaDesc.getName());
return queryMeta;
}
private SchemaItem getDimension(DimSchemaResp dimSchemaDesc) {
SchemaItem queryMeta = new SchemaItem();
queryMeta.setId(dimSchemaDesc.getId());
queryMeta.setBizName(dimSchemaDesc.getBizName());
queryMeta.setName(dimSchemaDesc.getName());
return queryMeta;
}
private void dealNativeQuery(SemanticParseInfo semanticParseInfo, boolean isNativeQuery) { private void dealNativeQuery(SemanticParseInfo semanticParseInfo, boolean isNativeQuery) {
if (Objects.nonNull(semanticParseInfo)) { if (Objects.nonNull(semanticParseInfo)) {
semanticParseInfo.setNativeQuery(isNativeQuery); semanticParseInfo.setNativeQuery(isNativeQuery);

View File

@@ -1,6 +1,6 @@
package com.tencent.supersonic.chat.application.query; package com.tencent.supersonic.chat.application.query;
import static com.tencent.supersonic.chat.api.pojo.SchemaElementType.METRIC; import static com.tencent.supersonic.chat.api.pojo.SchemaElementType.*;
import static com.tencent.supersonic.chat.application.query.QueryMatchOption.RequireNumberType.AT_LEAST; import static com.tencent.supersonic.chat.application.query.QueryMatchOption.RequireNumberType.AT_LEAST;
import static com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption.REQUIRED; import static com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption.REQUIRED;

View File

@@ -16,6 +16,7 @@ import com.tencent.supersonic.chat.domain.utils.ContextHelper;
import com.tencent.supersonic.common.pojo.SchemaItem; import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum; import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -95,7 +96,7 @@ public class MetricCompare extends MetricSemanticQuery {
if (toAdd.isPresent()) { if (toAdd.isPresent()) {
if (FilterOperatorEnum.EQUALS.equals(toAdd.get().getOperator()) || FilterOperatorEnum.IN.equals( if (FilterOperatorEnum.EQUALS.equals(toAdd.get().getOperator()) || FilterOperatorEnum.IN.equals(
toAdd.get().getOperator())) { toAdd.get().getOperator())) {
List<Object> vals = new ArrayList<>(); Set<Object> vals = new HashSet<>();
if (toAdd.get().getOperator().equals(FilterOperatorEnum.IN)) { if (toAdd.get().getOperator().equals(FilterOperatorEnum.IN)) {
vals.addAll((List<Object>) (toAdd.get().getValue())); vals.addAll((List<Object>) (toAdd.get().getValue()));
} else { } else {
@@ -106,7 +107,7 @@ public class MetricCompare extends MetricSemanticQuery {
} else { } else {
vals.add(filter.getValue()); vals.add(filter.getValue());
} }
toAdd.get().setValue(vals); toAdd.get().setValue(new ArrayList<>(vals));
toAdd.get().setOperator(FilterOperatorEnum.IN); toAdd.get().setOperator(FilterOperatorEnum.IN);
continue; continue;
} }

View File

@@ -2,7 +2,6 @@ package com.tencent.supersonic.chat.application.query;
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch; import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
import com.tencent.supersonic.chat.api.pojo.SchemaElementType; import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption; import com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption;
import com.tencent.supersonic.common.enums.AggregateTypeEnum; import com.tencent.supersonic.common.enums.AggregateTypeEnum;
@@ -12,10 +11,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import lombok.Data; import lombok.Data;
import lombok.ToString; import lombok.ToString;

View File

@@ -1,3 +1,4 @@
package com.tencent.supersonic.chat.application.query; package com.tencent.supersonic.chat.application.query;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
@@ -24,7 +25,6 @@ import java.util.*;
public abstract class RuleSemanticQuery implements SemanticQuery, Serializable { public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
protected SemanticParseInfo parseInfo = new SemanticParseInfo(); protected SemanticParseInfo parseInfo = new SemanticParseInfo();
protected List<SchemaElementMatch> schemaElementMatches = new ArrayList<>();
protected QueryMatcher queryMatcher = new QueryMatcher(); protected QueryMatcher queryMatcher = new QueryMatcher();
protected SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer(); protected SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
@@ -32,7 +32,8 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
RuleSemanticQueryManager.register(this); RuleSemanticQueryManager.register(this);
} }
public List<SchemaElementMatch> match(List<SchemaElementMatch> candidateElementMatches, QueryContextReq queryCtx) { public List<SchemaElementMatch> match(List<SchemaElementMatch> candidateElementMatches,
QueryContextReq queryCtx) {
return queryMatcher.match(candidateElementMatches); return queryMatcher.match(candidateElementMatches);
} }
@@ -57,6 +58,7 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
QueryResultWithSchemaResp queryResult = semanticLayer.queryByStruct( QueryResultWithSchemaResp queryResult = semanticLayer.queryByStruct(
SchemaInfoConverter.convertTo(parseInfo), user); SchemaInfoConverter.convertTo(parseInfo), user);
if (queryResult != null) { if (queryResult != null) {
queryResponse.setQueryAuthorization(queryResult.getQueryAuthorization()); queryResponse.setQueryAuthorization(queryResult.getQueryAuthorization());
} }
@@ -84,4 +86,4 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
public void setParseInfo(SemanticParseInfo parseInfo) { public void setParseInfo(SemanticParseInfo parseInfo) {
this.parseInfo = parseInfo; this.parseInfo = parseInfo;
} }
} }

View File

@@ -16,8 +16,4 @@ public class LLMConfig {
@Value("${query2sql.path:query2sql}") @Value("${query2sql.path:query2sql}")
private String queryToSqlPath; private String queryToSqlPath;
@Value("${query2sql.endpoint:}")
private String endpoint;
} }

View File

@@ -15,29 +15,11 @@ public class ChatConfigDO {
private Long id; private Long id;
private Long domainId; private Long domainId;
/**
* default metrics information about the domain
*/
private String defaultMetrics;
/** private String chatDetailConfig;
* invisible dimensions/metrics
*/
private String visibility;
/** private String chatAggConfig;
* the entity info about the domain
*/
private String entity;
/**
* information about dictionary about the domain
*/
private String knowledgeInfo;
/**
* available status
*/
private Integer status; private Integer status;
/** /**

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import lombok.Data;
import java.util.List;
@Data
public class ChatAggConfig {
/**
* invisible dimensions/metrics
*/
private ItemVisibility visibility;
/**
* information about dictionary about the domain
*/
private List<KnowledgeInfo> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultConfig chatDefaultConfig;
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import lombok.Data;
import java.util.List;
@Data
public class ChatAggRichConfig {
/**
* invisible dimensions/metrics
*/
private ItemVisibilityInfo visibility;
/**
* information about dictionary about the domain
*/
private List<KnowledgeInfo> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultRichConfig chatDefaultConfig;
}

View File

@@ -16,25 +16,16 @@ public class ChatConfig {
private Long id; private Long id;
private Long domainId; private Long domainId;
/**
* default metrics information about the domain
*/
private List<DefaultMetricInfo> defaultMetrics;
/** /**
* invisible dimensions/metrics * the chatDetailConfig about the domain
*/ */
private ItemVisibility visibility; private ChatDetailConfig chatDetailConfig;
/** /**
* the entity info about the domain * the chatAggConfig about the domain
*/ */
private Entity entity; private ChatAggConfig chatAggConfig;
/**
* information about dictionary about the domain
*/
private List<KnowledgeInfo> knowledgeInfos;
/** /**
* available status * available status

View File

@@ -0,0 +1,34 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.enums.StatusEnum;
import java.util.List;
import lombok.Data;
import lombok.ToString;
/**
* extended information command about domain
*/
@Data
@ToString
public class ChatConfigBaseReq {
private Long domainId;
/**
* the chatDetailConfig about the domain
*/
private ChatDetailConfig chatDetailConfig;
/**
* the chatAggConfig about the domain
*/
private ChatAggConfig chatAggConfig;
/**
* available status
*/
private StatusEnum status;
}

View File

@@ -4,7 +4,7 @@ import lombok.Data;
@Data @Data
public class ChatConfigEditReq extends ChatConfigBase { public class ChatConfigEditReqReq extends ChatConfigBaseReq {
private Long id; private Long id;
} }

View File

@@ -1,44 +0,0 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.enums.StatusEnum;
import java.util.Date;
import java.util.List;
import lombok.Data;
@Data
public class ChatConfigInfo {
private Long id;
private Long domainId;
/**
* default metrics information about the domain
*/
private List<DefaultMetricInfo> defaultMetrics;
/**
* invisible dimensions/metrics
*/
private ItemVisibility visibility;
/**
* the entity info about the domain
*/
private Entity entity;
/**
* information about dictionary about the domain
*/
private List<KnowledgeInfo> knowledgeInfos;
/**
* available status
*/
private StatusEnum statusEnum;
private String createdBy;
private String updatedBy;
private Date createdAt;
private Date updatedAt;
}

View File

@@ -0,0 +1,27 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.enums.StatusEnum;
import java.util.Date;
import lombok.Data;
@Data
public class ChatConfigResp {
private Long id;
private Long domainId;
private ChatDetailConfig chatDetailConfig;
private ChatAggConfig chatAggConfig;
/**
* available status
*/
private StatusEnum statusEnum;
private String createdBy;
private String updatedBy;
private Date createdAt;
private Date updatedAt;
}

View File

@@ -1,47 +0,0 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.enums.StatusEnum;
import java.util.Date;
import java.util.List;
import lombok.Data;
@Data
public class ChatConfigRichInfo {
private Long id;
private Long domainId;
private String name;
private String bizName;
/**
* default metrics information about the domain
*/
private List<DefaultMetric> defaultMetrics;
/**
* invisible dimensions/metrics
*/
private ItemVisibilityInfo visibility;
/**
* the entity info about the domain
*/
private EntityRichInfo entity;
/**
* information about dictionary about the domain
*/
private List<KnowledgeInfo> knowledgeInfos;
/**
* available status
*/
private StatusEnum statusEnum;
private String createdBy;
private String updatedBy;
private Date createdAt;
private Date updatedAt;
}

View File

@@ -0,0 +1,31 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.enums.StatusEnum;
import java.util.Date;
import java.util.List;
import lombok.Data;
@Data
public class ChatConfigRichResp {
private Long id;
private Long domainId;
private String domainName;
private String bizName;
private ChatAggRichConfig chatAggRichConfig;
private ChatDetailRichConfig chatDetailRichConfig;
/**
* available status
*/
private StatusEnum statusEnum;
private String createdBy;
private String updatedBy;
private Date createdAt;
private Date updatedAt;
}

View File

@@ -0,0 +1,27 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.constant.Constants;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ChatDefaultConfig {
private List<Long> dimensionIds = new ArrayList<>();
private List<Long> metricIds = new ArrayList<>();
/**
* default time span unit
*/
private Integer unit = 1;
/**
* default time type: day
* DAY, WEEK, MONTH, YEAR
*/
private String period = Constants.DAY;
}

View File

@@ -0,0 +1,27 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.constant.Constants;
import com.tencent.supersonic.common.pojo.SchemaItem;
import lombok.Data;
import java.util.List;
@Data
public class ChatDefaultRichConfig {
private List<SchemaItem> dimensions;
private List<SchemaItem> metrics;
/**
* default time span unit
*/
private Integer unit = 1;
/**
* default time type: day
* DAY, WEEK, MONTH, YEAR
*/
private String period = Constants.DAY;
}

View File

@@ -1,41 +1,29 @@
package com.tencent.supersonic.chat.domain.pojo.config; package com.tencent.supersonic.chat.domain.pojo.config;
import com.tencent.supersonic.common.enums.StatusEnum;
import java.util.List;
import lombok.Data; import lombok.Data;
import lombok.ToString;
/** import java.util.List;
* extended information command about domain
*/
@Data @Data
@ToString public class ChatDetailConfig {
public class ChatConfigBase {
private Long domainId;
/**
* default metrics information about the domain
*/
private List<DefaultMetricInfo> defaultMetrics;
/** /**
* invisible dimensions/metrics * invisible dimensions/metrics
*/ */
private ItemVisibility visibility; private ItemVisibility visibility;
/**
* the entity info about the domain
*/
private Entity entity;
/** /**
* information about dictionary about the domain * information about dictionary about the domain
*/ */
private List<KnowledgeInfo> knowledgeInfos; private List<KnowledgeInfo> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultConfig chatDefaultConfig;
/** /**
* available status * the entity info about the domain
*/ */
private StatusEnum status; private Entity entity;
} }

View File

@@ -0,0 +1,30 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import lombok.Data;
import java.util.List;
@Data
public class ChatDetailRichConfig {
/**
* invisible dimensions/metrics
*/
private ItemVisibilityInfo visibility;
/**
* the entity info about the domain
*/
private EntityRichInfo entity;
/**
* information about dictionary about the domain
*/
private List<KnowledgeInfo> knowledgeInfos;
private KnowledgeAdvancedConfig globalKnowledgeConfig;
private ChatDefaultRichConfig chatDefaultConfig;
}

View File

@@ -3,11 +3,13 @@ package com.tencent.supersonic.chat.domain.pojo.config;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString; import lombok.ToString;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ToString @ToString
@NoArgsConstructor
public class Dim4Dict { public class Dim4Dict {
private Long dimId; private Long dimId;

View File

@@ -18,16 +18,12 @@ public class Entity {
/** /**
* uniquely identifies an entity * uniquely identifies an entity
*/ */
private List<Long> entityIds; private Long entityId;
/** /**
* entity name list * entity name list
*/ */
private List<String> names; private List<String> names;
/**
* query entity default information
*/
private EntityDetailData detailData;
} }

View File

@@ -7,14 +7,14 @@ import lombok.Data;
@Data @Data
public class EntityRichInfo { public class EntityRichInfo {
private Long domainId; // private Long domainId;
private String domainName; // private String domainName;
private String domainBizName; // private String domainBizName;
/**
* entity alias
*/
private List<String> names; private List<String> names;
private List<DimSchemaResp> entityIds; private DimSchemaResp dimItem;
private EntityInternalDetail entityInternalDetailDesc;
} }

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.chat.domain.pojo.config; package com.tencent.supersonic.chat.domain.pojo.config;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import lombok.Data; import lombok.Data;
import lombok.ToString; import lombok.ToString;
@@ -12,10 +13,10 @@ public class ItemVisibility {
/** /**
* invisible dimensions * invisible dimensions
*/ */
private List<Long> blackDimIdList; private List<Long> blackDimIdList = new ArrayList<>();
/** /**
* invisible metrics * invisible metrics
*/ */
private List<Long> blackMetricIdList; private List<Long> blackMetricIdList = new ArrayList<>();
} }

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.chat.domain.pojo.config;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* advanced knowledge config
*/
@Data
public class KnowledgeAdvancedConfig {
private List<String> blackList = new ArrayList<>();
private List<String> whiteList = new ArrayList<>();
private List<String> ruleList = new ArrayList<>();
}

View File

@@ -27,9 +27,12 @@ public class KnowledgeInfo {
@NotNull @NotNull
private TypeEnums type = TypeEnums.DIMENSION; private TypeEnums type = TypeEnums.DIMENSION;
private List<String> blackList; private Boolean searchEnable = false;
private List<String> whiteList;
private List<String> ruleList; /**
private Boolean isDictInfo; * advanced knowledge config for single item
*/
private KnowledgeAdvancedConfig knowledgeAdvancedConfig;
} }

View File

@@ -3,7 +3,7 @@ package com.tencent.supersonic.chat.domain.repository;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfig; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfig;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
import java.util.List; import java.util.List;
@@ -13,7 +13,7 @@ public interface ChatConfigRepository {
Long updateConfig(ChatConfig chaConfig); Long updateConfig(ChatConfig chaConfig);
List<ChatConfigInfo> getChatConfig(ChatConfigFilter filter); List<ChatConfigResp> getChatConfig(ChatConfigFilter filter);
ChatConfigInfo getConfigByDomainId(Long domainId); ChatConfigResp getConfigByDomainId(Long domainId);
} }

View File

@@ -2,22 +2,25 @@ package com.tencent.supersonic.chat.domain.service;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBase; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBaseReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReq; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReqReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import java.util.List; import java.util.List;
public interface ConfigService { public interface ConfigService {
Long addConfig(ChatConfigBase extendBaseCmd, User user); Long addConfig(ChatConfigBaseReq extendBaseCmd, User user);
Long editConfig(ChatConfigEditReq extendEditCmd, User user); Long editConfig(ChatConfigEditReqReq extendEditCmd, User user);
List<ChatConfigInfo> search(ChatConfigFilter filter, User user); List<ChatConfigResp> search(ChatConfigFilter filter, User user);
ChatConfigRichInfo getConfigRichInfo(Long domainId); ChatConfigRichResp getConfigRichInfo(Long domainId);
List<ChatConfigRichInfo> getAllChatRichConfig(); ChatConfigResp fetchConfigByDomainId(Long domainId);
List<ChatConfigRichResp> getAllChatRichConfig();
} }

View File

@@ -3,20 +3,11 @@ package com.tencent.supersonic.chat.domain.utils;
import static com.tencent.supersonic.common.constant.Constants.ADMIN_LOWER; import static com.tencent.supersonic.common.constant.Constants.ADMIN_LOWER;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.domain.pojo.config.*;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO; import com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfig;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBase;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo;
import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetricInfo;
import com.tencent.supersonic.chat.domain.pojo.config.Entity;
import com.tencent.supersonic.chat.domain.pojo.config.EntityDetailData;
import com.tencent.supersonic.chat.domain.pojo.config.EntityInternalDetail;
import com.tencent.supersonic.chat.domain.pojo.config.ItemVisibility;
import com.tencent.supersonic.chat.domain.pojo.config.KnowledgeInfo;
import com.tencent.supersonic.common.enums.StatusEnum; import com.tencent.supersonic.common.enums.StatusEnum;
import com.tencent.supersonic.common.util.RecordInfo; import com.tencent.supersonic.common.util.RecordInfo;
import com.tencent.supersonic.common.util.json.JsonUtil; import com.tencent.supersonic.common.util.json.JsonUtil;
@@ -39,31 +30,28 @@ import org.springframework.util.CollectionUtils;
@Slf4j @Slf4j
public class ChatConfigUtils { public class ChatConfigUtils {
public ChatConfig newChatConfig(ChatConfigBase extendBaseCmd, User user) { public ChatConfig newChatConfig(ChatConfigBaseReq extendBaseCmd, User user) {
ChatConfig chaConfig = new ChatConfig(); ChatConfig chatConfig = new ChatConfig();
BeanUtils.copyProperties(extendBaseCmd, chatConfig);
BeanUtils.copyProperties(extendBaseCmd, chaConfig);
RecordInfo recordInfo = new RecordInfo(); RecordInfo recordInfo = new RecordInfo();
String creator = (Objects.isNull(user) || Strings.isEmpty(user.getName())) ? ADMIN_LOWER : user.getName(); String creator = (Objects.isNull(user) || Strings.isEmpty(user.getName())) ? ADMIN_LOWER : user.getName();
recordInfo.createdBy(creator); recordInfo.createdBy(creator);
chaConfig.setRecordInfo(recordInfo); chatConfig.setRecordInfo(recordInfo);
chaConfig.setStatus(StatusEnum.ONLINE); chatConfig.setStatus(StatusEnum.ONLINE);
return chaConfig; return chatConfig;
} }
public ChatConfig editChaConfig(ChatConfigEditReq extendEditCmd, User facadeUser) { public ChatConfig editChatConfig(ChatConfigEditReqReq extendEditCmd, User facadeUser) {
ChatConfig chaConfig = new ChatConfig(); ChatConfig chatConfig = new ChatConfig();
BeanUtils.copyProperties(extendEditCmd, chaConfig);
BeanUtils.copyProperties(extendEditCmd, chatConfig);
RecordInfo recordInfo = new RecordInfo(); RecordInfo recordInfo = new RecordInfo();
String user = (Objects.isNull(facadeUser) || Strings.isEmpty(facadeUser.getName())) String user = (Objects.isNull(facadeUser) || Strings.isEmpty(facadeUser.getName()))
? ADMIN_LOWER : facadeUser.getName(); ? ADMIN_LOWER : facadeUser.getName();
recordInfo.updatedBy(user); recordInfo.updatedBy(user);
chaConfig.setRecordInfo(recordInfo); chatConfig.setRecordInfo(recordInfo);
return chaConfig; return chatConfig;
} }
@@ -126,45 +114,76 @@ public class ChatConfigUtils {
return new ArrayList<>(metricIdAndDescPair.keySet()); return new ArrayList<>(metricIdAndDescPair.keySet());
} }
public ChatConfigDO chatConfig2DO(ChatConfig chaConfig) { public ChatConfigDO chatConfig2DO(ChatConfig chatConfig) {
ChatConfigDO chaConfigDO = new ChatConfigDO(); ChatConfigDO chatConfigDO = new ChatConfigDO();
BeanUtils.copyProperties(chaConfig, chaConfigDO); BeanUtils.copyProperties(chatConfig, chatConfigDO);
chaConfigDO.setDefaultMetrics(JsonUtil.toString(chaConfig.getDefaultMetrics())); chatConfigDO.setChatAggConfig(JsonUtil.toString(chatConfig.getChatAggConfig()));
chaConfigDO.setVisibility(JsonUtil.toString(chaConfig.getVisibility())); chatConfigDO.setChatDetailConfig(JsonUtil.toString(chatConfig.getChatDetailConfig()));
chaConfigDO.setEntity(JsonUtil.toString(chaConfig.getEntity()));
chaConfigDO.setKnowledgeInfo(JsonUtil.toString(chaConfig.getKnowledgeInfos()));
if (Objects.isNull(chaConfig.getStatus())) { if (Objects.isNull(chatConfig.getStatus())) {
chaConfigDO.setStatus(null); chatConfigDO.setStatus(null);
} else { } else {
chaConfigDO.setStatus(chaConfig.getStatus().getCode()); chatConfigDO.setStatus(chatConfig.getStatus().getCode());
} }
chaConfigDO.setCreatedBy(chaConfig.getRecordInfo().getCreatedBy()); chatConfigDO.setCreatedBy(chatConfig.getRecordInfo().getCreatedBy());
chaConfigDO.setCreatedAt(chaConfig.getRecordInfo().getCreatedAt()); chatConfigDO.setCreatedAt(chatConfig.getRecordInfo().getCreatedAt());
chaConfigDO.setUpdatedBy(chaConfig.getRecordInfo().getUpdatedBy()); chatConfigDO.setUpdatedBy(chatConfig.getRecordInfo().getUpdatedBy());
chaConfigDO.setUpdatedAt(chaConfig.getRecordInfo().getUpdatedAt()); chatConfigDO.setUpdatedAt(chatConfig.getRecordInfo().getUpdatedAt());
return chaConfigDO; return chatConfigDO;
} }
public ChatConfigInfo chatConfigDO2Descriptor(ChatConfigDO chaConfigDO) { public ChatConfigResp chatConfigDO2Descriptor(Long domainId, ChatConfigDO chatConfigDO) {
ChatConfigInfo chaConfigDescriptor = new ChatConfigInfo(); ChatConfigResp chatConfigDescriptor = new ChatConfigResp();
BeanUtils.copyProperties(chaConfigDO, chaConfigDescriptor);
chaConfigDescriptor.setDefaultMetrics( if (Objects.isNull(chatConfigDO)) {
JsonUtil.toList(chaConfigDO.getDefaultMetrics(), DefaultMetricInfo.class)); // deal empty chatConfigDO
chaConfigDescriptor.setVisibility(JsonUtil.toObject(chaConfigDO.getVisibility(), ItemVisibility.class)); return generateEmptyChatConfigResp(domainId);
chaConfigDescriptor.setEntity(JsonUtil.toObject(chaConfigDO.getEntity(), Entity.class)); }
chaConfigDescriptor.setKnowledgeInfos(JsonUtil.toList(chaConfigDO.getKnowledgeInfo(), KnowledgeInfo.class));
chaConfigDescriptor.setStatusEnum(StatusEnum.of(chaConfigDO.getStatus()));
chaConfigDescriptor.setCreatedBy(chaConfigDO.getCreatedBy()); BeanUtils.copyProperties(chatConfigDO, chatConfigDescriptor);
chaConfigDescriptor.setCreatedAt(chaConfigDO.getCreatedAt());
chaConfigDescriptor.setUpdatedBy(chaConfigDO.getUpdatedBy());
chaConfigDescriptor.setUpdatedAt(chaConfigDO.getUpdatedAt());
return chaConfigDescriptor; chatConfigDescriptor.setChatDetailConfig(JsonUtil.toObject(chatConfigDO.getChatDetailConfig(), ChatDetailConfig.class));
chatConfigDescriptor.setChatAggConfig(JsonUtil.toObject(chatConfigDO.getChatAggConfig(), ChatAggConfig.class));
chatConfigDescriptor.setStatusEnum(StatusEnum.of(chatConfigDO.getStatus()));
chatConfigDescriptor.setCreatedBy(chatConfigDO.getCreatedBy());
chatConfigDescriptor.setCreatedAt(chatConfigDO.getCreatedAt());
chatConfigDescriptor.setUpdatedBy(chatConfigDO.getUpdatedBy());
chatConfigDescriptor.setUpdatedAt(chatConfigDO.getUpdatedAt());
if (Strings.isEmpty(chatConfigDO.getChatAggConfig())) {
chatConfigDescriptor.setChatAggConfig(generateEmptyChatAggConfigResp());
}
if (Strings.isEmpty(chatConfigDO.getChatDetailConfig())) {
chatConfigDescriptor.setChatDetailConfig(generateEmptyChatDetailConfigResp());
}
return chatConfigDescriptor;
}
private ChatConfigResp generateEmptyChatConfigResp(Long domainId) {
ChatConfigResp chatConfigResp = new ChatConfigResp();
chatConfigResp.setDomainId(domainId);
chatConfigResp.setChatDetailConfig(generateEmptyChatDetailConfigResp());
chatConfigResp.setChatAggConfig(generateEmptyChatAggConfigResp());
return chatConfigResp;
}
private ChatDetailConfig generateEmptyChatDetailConfigResp() {
ChatDetailConfig chatDetailConfig = new ChatDetailConfig();
ItemVisibility visibility = new ItemVisibility();
chatDetailConfig.setVisibility(visibility);
return chatDetailConfig;
}
private ChatAggConfig generateEmptyChatAggConfigResp() {
ChatAggConfig chatAggConfig = new ChatAggConfig();
ItemVisibility visibility = new ItemVisibility();
chatAggConfig.setVisibility(visibility);
return chatAggConfig;
} }
} }

View File

@@ -1,24 +1,24 @@
package com.tencent.supersonic.chat.domain.utils; package com.tencent.supersonic.chat.domain.utils;
import com.tencent.supersonic.chat.api.component.SemanticQuery;
import com.tencent.supersonic.chat.api.pojo.ChatContext; import com.tencent.supersonic.chat.api.pojo.ChatContext;
import com.tencent.supersonic.chat.api.pojo.Filter; import com.tencent.supersonic.chat.api.pojo.Filter;
import com.tencent.supersonic.chat.api.pojo.QueryMatchInfo; import com.tencent.supersonic.chat.api.pojo.QueryMatchInfo;
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch; import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
import com.tencent.supersonic.chat.api.pojo.SchemaElementType; import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo; import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.api.component.SemanticQuery; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
import com.tencent.supersonic.common.pojo.SchemaItem; import com.tencent.supersonic.common.pojo.SchemaItem;
import java.util.Set; import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import org.apache.commons.lang3.StringUtils; import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
import org.springframework.util.CollectionUtils; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
public class ContextHelper { public class ContextHelper {
@@ -137,17 +137,18 @@ public class ContextHelper {
return difference; return difference;
} }
public static void setEntityId(Long dimensionId, String value, ChatConfigRichInfo chaConfigRichDesc, public static void setEntityId(Long dimensionId, String value, ChatConfigRichResp chaConfigRichDesc,
SemanticParseInfo semanticParseInfo) { SemanticParseInfo semanticParseInfo) {
if (chaConfigRichDesc != null && chaConfigRichDesc.getEntity() != null) { if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null
Optional<DimSchemaResp> dimensionDesc = chaConfigRichDesc.getEntity().getEntityIds().stream() && chaConfigRichDesc.getChatDetailRichConfig().getEntity() != null) {
.filter(i -> i.getId().equals(dimensionId)).findFirst(); DimSchemaResp dimSchemaResp = chaConfigRichDesc.getChatDetailRichConfig().getEntity().getDimItem();
if (dimensionDesc.isPresent() && StringUtils.isNumeric(value)) { if (Objects.nonNull(dimSchemaResp) && StringUtils.isNumeric(value)) {
semanticParseInfo.setEntity(Long.valueOf(value)); semanticParseInfo.setEntity(Long.valueOf(value));
} }
} }
} }
public static boolean hasEntityId(ChatContext chatCtx) { public static boolean hasEntityId(ChatContext chatCtx) {
if (chatCtx != null && chatCtx.getParseInfo() != null) { if (chatCtx != null && chatCtx.getParseInfo() != null) {
return chatCtx.getParseInfo().getEntity() > 0; return chatCtx.getParseInfo().getEntity() > 0;
@@ -198,9 +199,17 @@ public class ContextHelper {
for (Filter chatFilter : contextSemanticParse.getDimensionFilters()) { for (Filter chatFilter : contextSemanticParse.getDimensionFilters()) {
if (!isInSchemaElementMatchList(elementMatches, SchemaElementType.VALUE, if (!isInSchemaElementMatchList(elementMatches, SchemaElementType.VALUE,
chatFilter.getValue().toString())) { chatFilter.getValue().toString())) {
toSchemaElementMatch.add( List<String> values = new ArrayList<>();
getSchemaElementMatchByContext(chatFilter.getElementID().intValue(), if (chatFilter.getOperator().equals(FilterOperatorEnum.IN)) {
chatFilter.getValue().toString(), SchemaElementType.VALUE)); values.addAll((List<String>) chatFilter.getValue());
} else {
values.add(chatFilter.getValue().toString());
}
for (String value : values) {
toSchemaElementMatch.add(
getSchemaElementMatchByContext(chatFilter.getElementID().intValue(),
value, SchemaElementType.VALUE));
}
} }
} }
} }
@@ -224,8 +233,7 @@ public class ContextHelper {
return false; return false;
} }
Long num = elementMatches.stream() Long num = elementMatches.stream()
.filter(element -> element != null && element.getWord() != null && element.getWord() .filter(element -> element != null && element.getElementType().equals(schemaElementType)).count();
.equalsIgnoreCase(word) && element.getElementType().equals(schemaElementType)).count();
return num > 0; return num > 0;
} }
@@ -247,6 +255,7 @@ public class ContextHelper {
.elementID(id) .elementID(id)
.elementType(schemaElementType) .elementType(schemaElementType)
.word(word) .word(word)
.detectWord(word)
.similarity(0.5) .similarity(0.5)
.build(); .build();
} }

View File

@@ -2,34 +2,33 @@ package com.tencent.supersonic.chat.domain.utils;
import static java.time.LocalDate.now; import static java.time.LocalDate.now;
import com.tencent.supersonic.chat.api.pojo.ChatContext; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch; import com.tencent.supersonic.chat.api.component.SemanticQuery;
import com.tencent.supersonic.chat.api.pojo.SchemaElementType; import com.tencent.supersonic.chat.api.pojo.*;
import com.tencent.supersonic.chat.api.pojo.SchemaMapInfo;
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.chat.api.request.QueryContextReq; import com.tencent.supersonic.chat.api.request.QueryContextReq;
import com.tencent.supersonic.chat.application.ConfigServiceImpl;
import com.tencent.supersonic.chat.application.parser.DomainResolver; import com.tencent.supersonic.chat.application.parser.DomainResolver;
import com.tencent.supersonic.chat.application.query.EntityDetail; import com.tencent.supersonic.chat.application.query.*;
import com.tencent.supersonic.chat.application.query.EntityListFilter; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import com.tencent.supersonic.chat.application.query.EntityListTopN; import com.tencent.supersonic.chat.domain.pojo.config.ChatDefaultRichConfig;
import com.tencent.supersonic.chat.application.query.EntityMetricFilter;
import com.tencent.supersonic.chat.application.query.MetricDomain;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetric;
import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.EntityRichInfo;
import com.tencent.supersonic.common.constant.Constants;
import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.DateConf;
import com.tencent.supersonic.common.pojo.SchemaItem; import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.common.util.context.ContextUtils; import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import java.util.ArrayList;
import java.util.HashSet; import java.util.*;
import java.util.LinkedHashSet; import java.util.function.Function;
import java.util.List; import java.util.stream.Collectors;
import java.util.Objects;
import java.util.Set; import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
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.beans.BeanUtils;
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;
@@ -37,64 +36,81 @@ import org.springframework.util.CollectionUtils;
@Component @Component
public class DefaultMetricUtils { public class DefaultMetricUtils {
@Autowired
private ConfigServiceImpl configService;
/** /**
* supplementary default metric date dimension * supplementary default metric date dimension
*/ */
public void injectDefaultMetric(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext, public void fillDefaultMetric(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext,
ChatContext chatContext) { ChatContext chatContext) {
String queryMode = semanticParseInfo.getQueryMode(); String queryMode = semanticParseInfo.getQueryMode();
ChatConfigRichInfo chaConfigRichDesc = null;
if (StringUtils.isNotEmpty(queryMode)) { if (StringUtils.isNotEmpty(queryMode)) {
Map<String, RuleSemanticQuery> semanticQuery = RuleSemanticQueryManager.getSemanticQueries().stream().collect(Collectors.toMap(RuleSemanticQuery::getQueryMode, Function.identity()));
RuleSemanticQuery ruleSemanticQuery = semanticQuery.get(queryMode);
if (semanticParseInfo == null) { if (semanticParseInfo == null) {
return; return;
} }
if (!EntityListFilter.QUERY_MODE.equals(queryMode)) { // if (!EntityListFilter.QUERY_MODE.equals(queryMode)) {
boolean isFillThemeDefaultMetricLogic = false; boolean isFillAggDefaultMetricLogic = false;
boolean isAddEntityDetailDimensionMetric = false; boolean isFillDetailDimensionMetric = false;
Integer domainId = queryContext.getDomainId().intValue(); Integer domainId = queryContext.getDomainId().intValue();
List<SchemaElementMatch> matchedElements = queryContext.getMapInfo().getMatchedElements(domainId); ChatDefaultRichConfig chatDefaultConfig = null;
Boolean isDetailMode = false;
List<SchemaElementMatch> matchedElements = queryContext.getMapInfo().getMatchedElements(domainId);
ChatConfigRichResp chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId());
if (Objects.isNull(chaConfigRichDesc)) {
return;
}
if (ruleSemanticQuery instanceof MetricSemanticQuery) {
if (!CollectionUtils.isEmpty(matchedElements)) { if (!CollectionUtils.isEmpty(matchedElements)) {
long metricCount = matchedElements.stream() long metricCount = matchedElements.stream()
.filter(schemaElementMatch -> schemaElementMatch.getElementType() .filter(schemaElementMatch -> schemaElementMatch.getElementType()
.equals(SchemaElementType.METRIC)).count(); .equals(SchemaElementType.METRIC)).count();
if (metricCount <= 0) { if (metricCount <= 0) {
if (chatContext.getParseInfo() == null if (chatContext.getParseInfo() == null
|| chatContext.getParseInfo().getMetrics() == null || chatContext.getParseInfo().getMetrics() == null
|| chatContext.getParseInfo().getMetrics().size() <= 0) { || chatContext.getParseInfo().getMetrics().size() <= 0) {
log.info("fillThemeDefaultMetricLogic");
isFillThemeDefaultMetricLogic = true; log.info("isFillAggDefaultMetricLogic is true");
isFillAggDefaultMetricLogic = true;
} }
} }
} else {
log.info("fillThemeDefaultMetricLogic for empty matchedElements ");
isFillThemeDefaultMetricLogic = true;
} }
if (EntityDetail.QUERY_MODE.equals(queryMode) || EntityMetricFilter.QUERY_MODE.equals(queryMode)) { if (Objects.nonNull(chaConfigRichDesc.getChatAggRichConfig())) {
isAddEntityDetailDimensionMetric = true; chatDefaultConfig = chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig();
dealNativeQuery(semanticParseInfo, queryContext, true);
} }
if (isFillThemeDefaultMetricLogic) { } else if (ruleSemanticQuery instanceof EntitySemanticQuery) {
if (chaConfigRichDesc == null) { log.info("fillThemeDefaultMetricLogic for empty matchedElements ");
chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId()); isFillDetailDimensionMetric = true;
} dealNativeQuery(semanticParseInfo, queryContext, true);
fillThemeDefaultMetricLogic(semanticParseInfo, chaConfigRichDesc, queryContext); isDetailMode = true;
if (Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig())) {
chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig();
} }
if (isAddEntityDetailDimensionMetric) {
if (chaConfigRichDesc == null) {
chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId());
}
addEntityDetailDimensionMetric(semanticParseInfo, chaConfigRichDesc, queryContext, chatContext);
}
fillDateDomain(semanticParseInfo, chatContext, chaConfigRichDesc, queryContext);
} }
if (isFillAggDefaultMetricLogic) {
fillDefaultMetricAggLogic(semanticParseInfo, chaConfigRichDesc, queryContext);
}
if (isFillDetailDimensionMetric) {
addEntityDetailDimensionMetric(semanticParseInfo, chaConfigRichDesc, queryContext, chatContext);
}
fillDateDomain(semanticParseInfo, chatContext, chaConfigRichDesc, chatDefaultConfig, isDetailMode);
// }
defaultQueryMode(semanticParseInfo, queryContext, chatContext); defaultQueryMode(semanticParseInfo, queryContext, chatContext);
addEntityTopDimension(semanticParseInfo, chaConfigRichDesc); addEntityTopDimension(semanticParseInfo, chaConfigRichDesc);
} }
} }
public void dealNativeQuery(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext, public void dealNativeQuery(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext,
boolean isNativeQuery) { boolean isNativeQuery) {
if (Objects.nonNull(queryContext) && Objects.nonNull(semanticParseInfo)) { if (Objects.nonNull(queryContext) && Objects.nonNull(semanticParseInfo)) {
semanticParseInfo.setNativeQuery(isNativeQuery); semanticParseInfo.setNativeQuery(isNativeQuery);
} }
@@ -102,22 +118,18 @@ public class DefaultMetricUtils {
public Set<String> addPrimaryDimension(EntityRichInfo entity, List<SchemaItem> dimensions) { public Set<String> addPrimaryDimension(EntityRichInfo entity, List<SchemaItem> dimensions) {
Set<String> primaryDimensions = new HashSet<>(); Set<String> primaryDimensions = new HashSet<>();
if (Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getEntityIds())) { if (Objects.isNull(entity) || Objects.isNull(entity.getDimItem())) {
return primaryDimensions; return primaryDimensions;
} }
entity.getEntityIds().stream().forEach(dimSchemaDesc -> { DimSchemaResp dimItem = entity.getDimItem();
SchemaItem dimension = new SchemaItem(); SchemaItem dimension = new SchemaItem();
//BeanUtils.copyProperties(dimSchemaDesc, dimension); BeanUtils.copyProperties(dimItem, dimension);
dimension.setName(dimSchemaDesc.getName()); dimensions.add(dimension);
dimension.setBizName(dimSchemaDesc.getBizName()); primaryDimensions.add(dimItem.getBizName());
dimension.setId(dimSchemaDesc.getId());
dimensions.add(dimension);
primaryDimensions.add(dimSchemaDesc.getBizName());
});
return primaryDimensions; return primaryDimensions;
} }
public void addEntityTopDimension(SemanticParseInfo semanticParseInfo, ChatConfigRichInfo chaConfigRichDesc) { public void addEntityTopDimension(SemanticParseInfo semanticParseInfo, ChatConfigRichResp chaConfigRichDesc) {
if (!semanticParseInfo.getQueryMode().equals(EntityListTopN.QUERY_MODE) || !semanticParseInfo.getDimensions() if (!semanticParseInfo.getQueryMode().equals(EntityListTopN.QUERY_MODE) || !semanticParseInfo.getDimensions()
.isEmpty()) { .isEmpty()) {
return; return;
@@ -127,44 +139,56 @@ public class DefaultMetricUtils {
if (chaConfigRichDesc == null) { if (chaConfigRichDesc == null) {
chaConfigRichDesc = getChatConfigRichInfo(domainId); chaConfigRichDesc = getChatConfigRichInfo(domainId);
} }
if (chaConfigRichDesc != null && chaConfigRichDesc.getEntity() != null) { if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null
&& chaConfigRichDesc.getChatDetailRichConfig().getEntity() != null) {
List<SchemaItem> dimensions = new ArrayList<>(); List<SchemaItem> dimensions = new ArrayList<>();
addPrimaryDimension(chaConfigRichDesc.getEntity(), dimensions); addPrimaryDimension(chaConfigRichDesc.getChatDetailRichConfig().getEntity(), dimensions);
semanticParseInfo.setDimensions(new HashSet<>(dimensions)); semanticParseInfo.setDimensions(new HashSet<>(dimensions));
semanticParseInfo.setLimit(1L); semanticParseInfo.setLimit(1L);
} }
} }
} }
public void addEntityDetailDimensionMetric(SemanticParseInfo semanticParseInfo, public void addEntityDetailDimensionMetric(SemanticParseInfo semanticParseInfo, ChatConfigRichResp chaConfigRichDesc, QueryContextReq queryContext,
ChatConfigRichInfo chaConfigRichDesc, QueryContextReq queryContext, ChatContext chatCtx) {
ChatContext chatCtx) {
if (semanticParseInfo.getDomainId() > 0) { if (semanticParseInfo.getDomainId() > 0) {
Long domainId = semanticParseInfo.getDomainId(); Long domainId = semanticParseInfo.getDomainId();
if (chaConfigRichDesc != null) { if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null) {
if (chaConfigRichDesc.getEntity() == null if (chaConfigRichDesc.getChatDetailRichConfig().getEntity() == null
|| chaConfigRichDesc.getEntity().getEntityInternalDetailDesc() == null) { || chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig() == null) {
return; return;
} }
List<SchemaElementMatch> schemaElementMatches = queryContext.getMapInfo() List<SchemaElementMatch> schemaElementMatches = queryContext.getMapInfo()
.getMatchedElements(domainId.intValue()); .getMatchedElements(domainId.intValue());
if (CollectionUtils.isEmpty(schemaElementMatches) || schemaElementMatches.stream() if (CollectionUtils.isEmpty(schemaElementMatches)
.filter(s -> SchemaElementType.DIMENSION.equals(s.getElementType())).count() <= 0) { || schemaElementMatches.stream().filter(s -> SchemaElementType.DIMENSION.equals(s.getElementType())).count() <= 0) {
log.info("addEntityDetailDimensionMetric catch"); log.info("addEntityDetailDimensionMetric catch");
Set<SchemaItem> dimensions = new LinkedHashSet(); if (CollectionUtils.isEmpty(semanticParseInfo.getDimensions())) {
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getDimensionList().stream() Set<SchemaItem> dimensions = new LinkedHashSet();
.forEach(m -> dimensions.add(getDimension(m))); List<SchemaItem> dimensionsConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig().getDimensions();
semanticParseInfo.setDimensions(dimensions); if (!CollectionUtils.isEmpty(dimensionsConfig)) {
dimensionsConfig.stream().forEach(m -> dimensions.add(m));
}
semanticParseInfo.setDimensions(dimensions);
}
if (CollectionUtils.isEmpty(semanticParseInfo.getMetrics())) {
Set<SchemaItem> metrics = new LinkedHashSet();
List<SchemaItem> metricsConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig().getMetrics();
if (!CollectionUtils.isEmpty(metricsConfig)) {
metricsConfig.stream().forEach(m -> metrics.add(m));
}
semanticParseInfo.setMetrics(metrics);
}
} }
} }
} }
} }
public void defaultQueryMode(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext, public void defaultQueryMode(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext,
ChatContext chatCtx) { ChatContext chatCtx) {
SchemaMapInfo schemaMap = queryContext.getMapInfo(); SchemaMapInfo schemaMap = queryContext.getMapInfo();
if (StringUtils.isEmpty(semanticParseInfo.getQueryMode())) { if (StringUtils.isEmpty(semanticParseInfo.getQueryMode())) {
if (chatCtx.getParseInfo() != null && chatCtx.getParseInfo().getDomainId() > 0) { if (chatCtx.getParseInfo() != null && chatCtx.getParseInfo().getDomainId() > 0) {
@@ -216,9 +240,94 @@ public class DefaultMetricUtils {
} }
} }
public void fillParseInfo(SemanticQuery query, Long domainId, String domainName) {
SemanticParseInfo parseInfo = query.getParseInfo();
parseInfo.setDomainId(domainId);
parseInfo.setDomainName(domainName);
parseInfo.setQueryMode(query.getQueryMode());
public void fillDateDomain(SemanticParseInfo parseInfo, ChatContext chatCtx, ChatConfigRichInfo chaConfigRichDesc,
QueryContextReq queryContext) { SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(parseInfo.getDomainId(), true);
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(parseInfo.getDomainId());
Map<Long, DimSchemaResp> dimensionDescMap = domainSchemaDesc.getDimensions().stream()
.collect(Collectors.toMap(DimSchemaResp::getId, Function.identity()));
Map<Long, MetricSchemaResp> metricDescMap = domainSchemaDesc.getMetrics().stream()
.collect(Collectors.toMap(MetricSchemaResp::getId, Function.identity()));
Map<Long, List<SchemaElementMatch>> dim2Values = new HashMap<>();
List<SchemaElementMatch> elementMatches = query.getParseInfo().getElementMatches();
for (SchemaElementMatch schemaMatch : elementMatches) {
Long elementID = Long.valueOf(schemaMatch.getElementID());
switch (schemaMatch.getElementType()) {
case ID:
case VALUE:
if (dimensionDescMap.containsKey(elementID)) {
if (dim2Values.containsKey(elementID)) {
dim2Values.get(elementID).add(schemaMatch);
} else {
dim2Values.put(elementID, new ArrayList<>(Arrays.asList(schemaMatch)));
}
}
break;
case DIMENSION:
DimSchemaResp dimensionDesc = dimensionDescMap.get(elementID);
if (dimensionDesc != null) {
SchemaItem dimensionParseInfo = new SchemaItem();
dimensionParseInfo.setBizName(dimensionDesc.getBizName());
dimensionParseInfo.setName(dimensionDesc.getName());
dimensionParseInfo.setId(dimensionDesc.getId());
parseInfo.getDimensions().add(dimensionParseInfo);
}
break;
case METRIC:
MetricSchemaResp metricDesc = metricDescMap.get(elementID);
if (metricDesc != null) {
SchemaItem metricItem = new SchemaItem();
metricItem.setBizName(metricDesc.getBizName());
metricItem.setName(metricDesc.getName());
metricItem.setId(metricDesc.getId());
metricItem.setCreatedAt(null);
metricItem.setUpdatedAt(null);
parseInfo.getMetrics().add(metricItem);
}
break;
default:
}
}
if (!dim2Values.isEmpty()) {
for (Map.Entry<Long, List<SchemaElementMatch>> entry : dim2Values.entrySet()) {
DimSchemaResp dimensionDesc = dimensionDescMap.get(entry.getKey());
if (entry.getValue().size() == 1) {
SchemaElementMatch schemaMatch = entry.getValue().get(0);
Filter dimensionFilter = new Filter();
dimensionFilter.setValue(schemaMatch.getWord());
dimensionFilter.setBizName(dimensionDesc.getBizName());
dimensionFilter.setName(dimensionDesc.getName());
dimensionFilter.setOperator(FilterOperatorEnum.EQUALS);
dimensionFilter.setElementID(Long.valueOf(schemaMatch.getElementID()));
parseInfo.getDimensionFilters().add(dimensionFilter);
ContextHelper.setEntityId(entry.getKey(), schemaMatch.getWord(), chaConfigRichDesc,
parseInfo);
} else {
Filter dimensionFilter = new Filter();
List<String> vals = new ArrayList<>();
entry.getValue().stream().forEach(i -> vals.add(i.getWord()));
dimensionFilter.setValue(vals);
dimensionFilter.setBizName(dimensionDesc.getBizName());
dimensionFilter.setName(dimensionDesc.getName());
dimensionFilter.setOperator(FilterOperatorEnum.IN);
dimensionFilter.setElementID(entry.getKey());
parseInfo.getDimensionFilters().add(dimensionFilter);
}
}
}
}
public void fillDateDomain(SemanticParseInfo parseInfo, ChatContext chatCtx, ChatConfigRichResp chaConfigRichDesc,
ChatDefaultRichConfig chatDefaultConfig, Boolean isDetailMode) {
//SemanticParseInfo parseInfo = queryContext.getParseInfo(); //SemanticParseInfo parseInfo = queryContext.getParseInfo();
if (parseInfo == null || parseInfo.getDateInfo() == null) { if (parseInfo == null || parseInfo.getDateInfo() == null) {
@@ -232,16 +341,18 @@ public class DefaultMetricUtils {
isUpdateTime = true; isUpdateTime = true;
} }
if (isUpdateTime && parseInfo != null && parseInfo.getDomainId() > 0) { if (isUpdateTime && parseInfo != null && parseInfo.getDomainId() > 0) {
fillThemeDefaultTime(parseInfo.getDomainId(), chaConfigRichDesc, parseInfo);
fillThemeDefaultTime(chaConfigRichDesc, parseInfo, chatDefaultConfig, isDetailMode);
} }
} }
} }
public void fillThemeDefaultMetricLogic(SemanticParseInfo semanticParseInfo, ChatConfigRichInfo chaConfigRichDesc, public void fillDefaultMetricAggLogic(SemanticParseInfo semanticParseInfo, ChatConfigRichResp chaConfigRichDesc, QueryContextReq queryContext) {
QueryContextReq queryContext) {
//SemanticParseInfo semanticParseInfo = queryContext.getParseInfo(); //SemanticParseInfo semanticParseInfo = queryContext.getParseInfo();
if (Objects.isNull(chaConfigRichDesc) || CollectionUtils.isEmpty(chaConfigRichDesc.getDefaultMetrics())) { if (Objects.isNull(chaConfigRichDesc) || Objects.isNull(chaConfigRichDesc.getChatAggRichConfig())
|| Objects.isNull(chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig())
|| CollectionUtils.isEmpty(chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig().getMetrics())) {
log.info("there is no defaultMetricIds info"); log.info("there is no defaultMetricIds info");
return; return;
} }
@@ -258,9 +369,9 @@ public class DefaultMetricUtils {
.filter(e -> e.getElementType().equals(SchemaElementType.DIMENSION)).count(); .filter(e -> e.getElementType().equals(SchemaElementType.DIMENSION)).count();
if (metricNum <= 0 && dimensionNum <= 0) { if (metricNum <= 0 && dimensionNum <= 0) {
Set<SchemaItem> metrics = new LinkedHashSet(); Set<SchemaItem> metrics = new LinkedHashSet();
chaConfigRichDesc.getDefaultMetrics().stream().forEach(metric -> { chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig().getMetrics().stream().forEach(metric -> {
SchemaItem metricTmp = new SchemaItem(); SchemaItem metricTmp = new SchemaItem();
metricTmp.setId(metric.getMetricId()); metricTmp.setId(metric.getId());
metricTmp.setBizName(metric.getBizName()); metricTmp.setBizName(metric.getBizName());
metrics.add(metricTmp); metrics.add(metricTmp);
}); });
@@ -269,18 +380,17 @@ public class DefaultMetricUtils {
if (Objects.isNull(semanticParseInfo.getDateInfo()) || Objects.isNull( if (Objects.isNull(semanticParseInfo.getDateInfo()) || Objects.isNull(
semanticParseInfo.getDateInfo().getDateMode())) { semanticParseInfo.getDateInfo().getDateMode())) {
DefaultMetric defaultMetricInfo = chaConfigRichDesc.getDefaultMetrics().get(0); ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig();
DateConf dateInfo = new DateConf(); DateConf dateInfo = new DateConf();
dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS); dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS);
dateInfo.setUnit(defaultMetricInfo.getUnit()); dateInfo.setUnit(chatDefaultConfig.getUnit());
dateInfo.setPeriod(defaultMetricInfo.getPeriod()); dateInfo.setPeriod(chatDefaultConfig.getPeriod());
semanticParseInfo.setDateInfo(dateInfo); semanticParseInfo.setDateInfo(dateInfo);
} }
} }
public void fillThemeDefaultTime(Long domain, ChatConfigRichInfo chaConfigRichDesc, public void fillThemeDefaultTime(ChatConfigRichResp chaConfigRichDesc, SemanticParseInfo semanticParseInfo, ChatDefaultRichConfig chatDefaultConfig, Boolean isDetailMode) {
SemanticParseInfo semanticParseInfo) {
if (!Objects.isNull(semanticParseInfo.getDateInfo()) && !Objects.isNull( if (!Objects.isNull(semanticParseInfo.getDateInfo()) && !Objects.isNull(
semanticParseInfo.getDateInfo().getDateMode())) { semanticParseInfo.getDateInfo().getDateMode())) {
return; return;
@@ -288,22 +398,26 @@ public class DefaultMetricUtils {
if (chaConfigRichDesc == null) { if (chaConfigRichDesc == null) {
chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId()); chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId());
} }
if (!Objects.isNull(chaConfigRichDesc) && !CollectionUtils.isEmpty(chaConfigRichDesc.getDefaultMetrics())) { if (!Objects.isNull(chaConfigRichDesc) && Objects.nonNull(chatDefaultConfig) && !CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())) {
DefaultMetric defaultMetricInfo = chaConfigRichDesc.getDefaultMetrics().get(0);
DateConf dateInfo = new DateConf(); DateConf dateInfo = new DateConf();
dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS); if (isDetailMode) {
dateInfo.setUnit(defaultMetricInfo.getUnit()); dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS);
dateInfo.setStartDate(now().minusDays(defaultMetricInfo.getUnit()).toString()); dateInfo.setUnit(1);
dateInfo.setEndDate(now().minusDays(1).toString()); dateInfo.setPeriod(Constants.DAY);
dateInfo.setPeriod(defaultMetricInfo.getPeriod()); } else {
dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS);
dateInfo.setUnit(chatDefaultConfig.getUnit());
dateInfo.setPeriod(chatDefaultConfig.getPeriod());
}
semanticParseInfo.setDateInfo(dateInfo); semanticParseInfo.setDateInfo(dateInfo);
log.info("fillThemeDefaultTime"); log.info("fillThemeDefaultTime");
} }
} }
public ChatConfigRichInfo getChatConfigRichInfo(Long domain) { public ChatConfigRichResp getChatConfigRichInfo(Long domain) {
DefaultSemanticInternalUtils defaultSemanticUtils = ContextUtils.getBean(DefaultSemanticInternalUtils.class); ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(domain);
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(domain);
return chaConfigRichDesc; return chaConfigRichDesc;
} }

View File

@@ -1,153 +0,0 @@
package com.tencent.supersonic.chat.domain.utils;
import static com.tencent.supersonic.common.constant.Constants.LIST_LOWER;
import static com.tencent.supersonic.common.constant.Constants.PAGESIZE_LOWER;
import static com.tencent.supersonic.common.constant.Constants.TOTAL_LOWER;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.core.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.core.response.DimensionResp;
import com.tencent.supersonic.semantic.api.core.response.DomainResp;
import com.tencent.supersonic.semantic.api.core.response.MetricResp;
import com.tencent.supersonic.chat.application.ConfigServiceImpl;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
import com.tencent.supersonic.common.result.ResultData;
import com.tencent.supersonic.common.result.ReturnCode;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import com.tencent.supersonic.common.util.context.ThreadContext;
import com.tencent.supersonic.common.util.json.JsonUtil;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
@Component
@Slf4j
public class DefaultSemanticInternalUtils {
@Value("${semantic.url.prefix:http://localhost:8081}")
private String semanticUrl;
@Value("${fetchDomainList.path:/api/semantic/schema/dimension/page}")
private String fetchDimensionPagePath;
@Value("${fetchDomainList.path:/api/semantic/schema/metric/page}")
private String fetchMetricPagePath;
@Value("${fetchDomainList.path:/api/semantic/schema/domain/list}")
private String fetchDomainListPath;
@Autowired
private RestTemplate restTemplate;
@Autowired
private ConfigServiceImpl chaConfigService;
@Autowired
private S2ThreadContext s2ThreadContext;
@Autowired
private AuthenticationConfig authenticationConfig;
public ChatConfigRichInfo getChatConfigRichInfo(Long domain) {
return chaConfigService.getConfigRichInfo(domain);
}
public PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd, User user) {
String body = JsonUtil.toString(pageMetricCmd);
Object dimensionListObject = fetchHttpResult(semanticUrl + fetchMetricPagePath, body, HttpMethod.POST);
LinkedHashMap map = (LinkedHashMap) dimensionListObject;
PageInfo<Object> metricDescObjectPageInfo = generatePageInfo(map);
PageInfo<MetricResp> metricDescPageInfo = new PageInfo<>();
BeanUtils.copyProperties(metricDescObjectPageInfo, metricDescPageInfo);
metricDescPageInfo.setList(metricDescPageInfo.getList());
return metricDescPageInfo;
}
public PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd, User user) {
String body = JsonUtil.toString(pageDimensionCmd);
Object dimensionListObject = fetchHttpResult(semanticUrl + fetchDimensionPagePath, body, HttpMethod.POST);
LinkedHashMap map = (LinkedHashMap) dimensionListObject;
PageInfo<Object> dimensionDescObjectPageInfo = generatePageInfo(map);
PageInfo<DimensionResp> dimensionDescPageInfo = new PageInfo<>();
BeanUtils.copyProperties(dimensionDescObjectPageInfo, dimensionDescPageInfo);
dimensionDescPageInfo.setList(dimensionDescPageInfo.getList());
return dimensionDescPageInfo;
}
private PageInfo<Object> generatePageInfo(LinkedHashMap map) {
PageInfo<Object> pageInfo = new PageInfo<>();
pageInfo.setList((List<Object>) map.get(LIST_LOWER));
Integer total = (Integer) map.get(TOTAL_LOWER);
pageInfo.setTotal(total);
Integer pageSize = (Integer) map.get(PAGESIZE_LOWER);
pageInfo.setPageSize(pageSize);
pageInfo.setPages((int) Math.ceil((double) total / pageSize));
return pageInfo;
}
public Object fetchHttpResult(String url, String bodyJson, HttpMethod httpMethod) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
fillToken(headers);
URI requestUrl = UriComponentsBuilder.fromHttpUrl(url).build().encode().toUri();
ParameterizedTypeReference<ResultData<Object>> responseTypeRef =
new ParameterizedTypeReference<ResultData<Object>>() {
};
HttpEntity<String> entity = new HttpEntity<>(JsonUtil.toString(bodyJson), headers);
try {
ResponseEntity<ResultData<Object>> responseEntity = restTemplate.exchange(requestUrl,
httpMethod, entity, responseTypeRef);
ResultData<Object> responseBody = responseEntity.getBody();
log.debug("ApiResponse<fetchDomainSchema> responseBody:{}", responseBody);
if (ReturnCode.SUCCESS.getCode() == responseBody.getCode()) {
Object data = responseBody.getData();
return data;
}
} catch (Exception e) {
throw new RuntimeException("fetchDomainSchema interface error", e);
}
throw new RuntimeException("fetchDomainSchema interface error");
}
public void fillToken(HttpHeaders headers) {
ThreadContext threadContext = s2ThreadContext.get();
if (Objects.nonNull(threadContext) && Strings.isNotEmpty(threadContext.getToken())) {
if (Objects.nonNull(authenticationConfig) && Strings.isNotEmpty(
authenticationConfig.getTokenHttpHeaderKey())) {
headers.set(authenticationConfig.getTokenHttpHeaderKey(), threadContext.getToken());
}
} else {
log.debug("threadContext is null:{}", Objects.isNull(threadContext));
}
}
public List<DomainResp> getDomainListForAdmin() {
Object domainDescListObject = fetchHttpResult(semanticUrl + fetchDomainListPath, null, HttpMethod.GET);
List<DomainResp> domainDescList = JsonUtil.toList(JsonUtil.toString(domainDescListObject), DomainResp.class);
return domainDescList;
}
}

View File

@@ -4,14 +4,12 @@ import static com.tencent.supersonic.common.constant.Constants.DAY;
import static com.tencent.supersonic.common.constant.Constants.UNDERLINE; import static com.tencent.supersonic.common.constant.Constants.UNDERLINE;
import com.tencent.supersonic.chat.api.component.SemanticLayer; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.application.ConfigServiceImpl;
import com.tencent.supersonic.chat.domain.pojo.config.*;
import com.tencent.supersonic.common.pojo.SchemaItem;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp; import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp;
import com.tencent.supersonic.chat.domain.dataobject.DimValueDO; import com.tencent.supersonic.chat.domain.dataobject.DimValueDO;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetric;
import com.tencent.supersonic.chat.domain.pojo.config.Dim4Dict;
import com.tencent.supersonic.chat.domain.pojo.config.ItemVisibilityInfo;
import com.tencent.supersonic.chat.domain.pojo.config.KnowledgeInfo;
import com.tencent.supersonic.knowledge.domain.pojo.DictUpdateMode; import com.tencent.supersonic.knowledge.domain.pojo.DictUpdateMode;
import com.tencent.supersonic.knowledge.domain.pojo.DimValue2DictCommand; import com.tencent.supersonic.knowledge.domain.pojo.DimValue2DictCommand;
@@ -25,6 +23,8 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.logging.log4j.util.Strings; import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -32,13 +32,15 @@ import org.springframework.util.CollectionUtils;
@Component @Component
public class DictMetaUtils { public class DictMetaUtils {
private final DefaultSemanticInternalUtils defaultSemanticUtils; @Autowired
private ConfigServiceImpl configService;
@Value("${model.internal.metric.suffix:internal_cnt}") @Value("${model.internal.metric.suffix:internal_cnt}")
private String internalMetricNameSuffix; private String internalMetricNameSuffix;
private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer(); private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
public DictMetaUtils(DefaultSemanticInternalUtils defaultSemanticUtils) { public DictMetaUtils() {
this.defaultSemanticUtils = defaultSemanticUtils;
} }
@@ -128,46 +130,66 @@ public class DictMetaUtils {
} }
private void fillDimValueDOList(List<DimValueDO> dimValueDOList, Long domainId, private void fillDimValueDOList(List<DimValueDO> dimValueDOList, Long domainId,
Map<Long, DimSchemaResp> dimIdAndDescPair) { Map<Long, DimSchemaResp> dimIdAndDescPair) {
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(domainId); ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(domainId);
if (Objects.nonNull(chaConfigRichDesc)) { if (Objects.nonNull(chaConfigRichDesc) && Objects.nonNull(chaConfigRichDesc.getChatAggRichConfig())) {
List<DefaultMetric> defaultMetricDescList = chaConfigRichDesc.getDefaultMetrics(); ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig();
List<KnowledgeInfo> knowledgeAggInfo = chaConfigRichDesc.getChatAggRichConfig().getKnowledgeInfos();
List<KnowledgeInfo> knowledgeInfos = chaConfigRichDesc.getKnowledgeInfos(); List<KnowledgeInfo> knowledgeDetailInfo = chaConfigRichDesc.getChatDetailRichConfig().getKnowledgeInfos();
if (!CollectionUtils.isEmpty(knowledgeInfos)) {
List<Dim4Dict> dimensions = new ArrayList<>();
knowledgeInfos.stream()
.filter(knowledgeInfo -> knowledgeInfo.getIsDictInfo()
&& isVisibleDim(knowledgeInfo, chaConfigRichDesc.getVisibility()))
.forEach(knowledgeInfo -> {
if (dimIdAndDescPair.containsKey(knowledgeInfo.getItemId())) {
DimSchemaResp dimensionDesc = dimIdAndDescPair.get(knowledgeInfo.getItemId());
//default cnt fillKnowledgeDimValue(knowledgeDetailInfo, chatDefaultConfig, dimValueDOList, dimIdAndDescPair, domainId);
if (CollectionUtils.isEmpty(defaultMetricDescList)) { fillKnowledgeDimValue(knowledgeAggInfo, chatDefaultConfig, dimValueDOList, dimIdAndDescPair, domainId);
String datasourceBizName = dimensionDesc.getDatasourceBizName();
if (Strings.isNotEmpty(datasourceBizName)) {
String internalMetricName = }
datasourceBizName + UNDERLINE + internalMetricNameSuffix; }
defaultMetricDescList.add(new DefaultMetric(internalMetricName, 2, DAY));
} private void fillKnowledgeDimValue(List<KnowledgeInfo> knowledgeInfos, ChatDefaultRichConfig chatDefaultConfig,
List<DimValueDO> dimValueDOList, Map<Long, DimSchemaResp> dimIdAndDescPair, Long domainId) {
if (!CollectionUtils.isEmpty(knowledgeInfos)) {
List<Dim4Dict> dimensions = new ArrayList<>();
List<DefaultMetric> defaultMetricDescList = new ArrayList<>();
knowledgeInfos.stream()
.filter(knowledgeInfo -> knowledgeInfo.getSearchEnable() && !CollectionUtils.isEmpty(dimIdAndDescPair)
&& dimIdAndDescPair.containsKey(knowledgeInfo.getItemId()))
.forEach(knowledgeInfo -> {
if (dimIdAndDescPair.containsKey(knowledgeInfo.getItemId())) {
DimSchemaResp dimensionDesc = dimIdAndDescPair.get(knowledgeInfo.getItemId());
//default cnt
if (Objects.isNull(chatDefaultConfig) || CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())) {
String datasourceBizName = dimensionDesc.getDatasourceBizName();
if (Strings.isNotEmpty(datasourceBizName)) {
String internalMetricName =
datasourceBizName + UNDERLINE + internalMetricNameSuffix;
defaultMetricDescList.add(new DefaultMetric(internalMetricName, 2, DAY));
} }
} else {
SchemaItem schemaItem = chatDefaultConfig.getMetrics().get(0);
defaultMetricDescList.add(new DefaultMetric(schemaItem.getBizName(), chatDefaultConfig.getUnit(), chatDefaultConfig.getPeriod()));
String bizName = dimensionDesc.getBizName();
dimensions.add(new Dim4Dict(knowledgeInfo.getItemId(), bizName,
knowledgeInfo.getBlackList(), knowledgeInfo.getWhiteList(),
knowledgeInfo.getRuleList()));
} }
}); String bizName = dimensionDesc.getBizName();
if (!CollectionUtils.isEmpty(dimensions)) { Dim4Dict dim4Dict = new Dim4Dict();
DimValueDO dimValueDO = new DimValueDO() dim4Dict.setDimId(knowledgeInfo.getItemId());
.setDomainId(domainId) dim4Dict.setBizName(bizName);
.setDefaultMetricIds(defaultMetricDescList) if(Objects.nonNull(knowledgeInfo.getKnowledgeAdvancedConfig())){
.setDimensions(dimensions); KnowledgeAdvancedConfig knowledgeAdvancedConfig = knowledgeInfo.getKnowledgeAdvancedConfig();
dimValueDOList.add(dimValueDO); BeanUtils.copyProperties(knowledgeAdvancedConfig, dim4Dict);
} }
dimensions.add(dim4Dict);
}
});
if (!CollectionUtils.isEmpty(dimensions)) {
DimValueDO dimValueDO = new DimValueDO()
.setDomainId(domainId)
.setDefaultMetricIds(defaultMetricDescList)
.setDimensions(dimensions);
dimValueDOList.add(dimValueDO);
} }
} }
} }
@@ -178,4 +200,4 @@ public class DictMetaUtils {
} }
return !itemVisibilityDesc.getBlackDimIdList().contains(knowledgeInfo.getItemId()); return !itemVisibilityDesc.getBlackDimIdList().contains(knowledgeInfo.getItemId());
} }
} }

View File

@@ -17,35 +17,36 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Slf4j
public class DslToSemanticInfo { public class DslToSemanticInfo {
public static final String SUB_TABLE = " ( select * from t_{0} where {1} >= ''{2}'' and {1} <= ''{3}'' ) as t_sub_{0}"; protected static final String SUB_TABLE = " ( select * from t_{0} where {1} >= ''{2}'' and {1} <= ''{3}'' ) as t_sub_{0}";
private static final Logger LOG = LoggerFactory.getLogger(DslToSemanticInfo.class);
public static String convert(SemanticParseInfo parseInfo, LLMResp llmResp) { public String convert(SemanticParseInfo parseInfo, LLMResp llmResp, Integer domainId) throws SqlParseException {
String sqlOutput = llmResp.getSqlOutput(); String sqlOutput = llmResp.getSqlOutput();
String domainName = llmResp.getDomainName(); String domainName = llmResp.getDomainName();
DomainInfos domainInfos = ContextUtils.getBean(WordNatureService.class).getCache().getUnchecked(""); // 1. extra deal with,such as add alias.
sqlOutput = extraConvert(sqlOutput, domainId);
SqlParserInfo sqlParseInfo = SqlParseUtils.getSqlParseInfo(sqlOutput); SqlParserInfo sqlParseInfo = SqlParseUtils.getSqlParseInfo(sqlOutput);
String tableName = sqlParseInfo.getTableName(); String tableName = sqlParseInfo.getTableName();
List<String> allFields = sqlParseInfo.getAllFields();
if (StringUtils.isEmpty(domainName)) { if (StringUtils.isEmpty(domainName)) {
domainName = tableName; domainName = tableName;
} }
List<String> allFields = sqlParseInfo.getAllFields(); // 2. replace the llm dsl, such as replace fieldName and tableName.
Map<String, Integer> domainNameToId = domainInfos.getDomains().stream() log.info("sqlParseInfo:{} ,domainName:{},domainId:{}", sqlParseInfo, domainName, domainId);
.collect(Collectors.toMap(ItemDO::getName, a -> a.getDomain(), (k1, k2) -> k1));
Integer domainId = domainNameToId.get(domainName);
LOG.info("sqlParseInfo:{} ,domainName:{},domainId:{}", sqlParseInfo, domainName, domainId);
DomainInfos domainInfos = ContextUtils.getBean(WordNatureService.class).getCache().getUnchecked("");
List<ItemDO> fieldList = domainInfos.getMetrics(); List<ItemDO> fieldList = domainInfos.getMetrics();
fieldList.addAll(domainInfos.getDimensions()); fieldList.addAll(domainInfos.getDimensions());
Map<String, String> fieldToBizName = getMapInfo(domainId, fieldList); Map<String, String> fieldToBizName = getMapInfo(domainId, fieldList);
@@ -56,6 +57,7 @@ public class DslToSemanticInfo {
sqlOutput = sqlOutput.replaceAll(fieldName, fieldBizName); sqlOutput = sqlOutput.replaceAll(fieldName, fieldBizName);
} }
} }
//3. deal with dayNo.
DateConf dateInfo = new DateConf(); DateConf dateInfo = new DateConf();
if (Objects.nonNull(parseInfo) && Objects.nonNull(parseInfo.getDateInfo())) { if (Objects.nonNull(parseInfo) && Objects.nonNull(parseInfo.getDateInfo())) {
dateInfo = parseInfo.getDateInfo(); dateInfo = parseInfo.getDateInfo();
@@ -72,15 +74,18 @@ public class DslToSemanticInfo {
TimeDimensionEnum timeDimension = TimeDimensionEnum.valueOf(period); TimeDimensionEnum timeDimension = TimeDimensionEnum.valueOf(period);
String dayField = timeDimension.getName(); String dayField = timeDimension.getName();
// add dayno
String subTable = MessageFormat.format(SUB_TABLE, domainId, dayField, startDate, endDate); String subTable = MessageFormat.format(SUB_TABLE, domainId, dayField, startDate, endDate);
String querySql = sqlOutput.replaceAll(tableName, subTable); String querySql = sqlOutput.replaceAll(tableName, subTable);
LOG.info("querySql:{},sqlOutput:{},dateInfo:{}", querySql, sqlOutput, dateInfo); log.info("querySql:{},sqlOutput:{},dateInfo:{}", querySql, sqlOutput, dateInfo);
return querySql; return querySql;
} }
private static Map<String, String> getMapInfo(Integer domainId, List<ItemDO> metrics) { protected String extraConvert(String sqlOutput, Integer domainId) throws SqlParseException {
return SqlParseUtils.addAliasToSql(sqlOutput);
}
protected Map<String, String> getMapInfo(Integer domainId, List<ItemDO> metrics) {
return metrics.stream().filter(entry -> entry.getDomain().equals(domainId)) return metrics.stream().filter(entry -> entry.getDomain().equals(domainId))
.collect(Collectors.toMap(ItemDO::getName, a -> a.getBizName(), (k1, k2) -> k1)); .collect(Collectors.toMap(ItemDO::getName, a -> a.getBizName(), (k1, k2) -> k1));
} }

View File

@@ -1,16 +1,16 @@
package com.tencent.supersonic.chat.infrastructure.repository; package com.tencent.supersonic.chat.infrastructure.repository;
import com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO; import com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfig; import com.tencent.supersonic.chat.domain.pojo.config.*;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilterInternal;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo;
import com.tencent.supersonic.chat.domain.repository.ChatConfigRepository; import com.tencent.supersonic.chat.domain.repository.ChatConfigRepository;
import com.tencent.supersonic.chat.domain.utils.ChatConfigUtils; import com.tencent.supersonic.chat.domain.utils.ChatConfigUtils;
import com.tencent.supersonic.chat.infrastructure.mapper.ChatConfigMapper; import com.tencent.supersonic.chat.infrastructure.mapper.ChatConfigMapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -24,7 +24,7 @@ public class ChatConfigRepositoryImpl implements ChatConfigRepository {
private final ChatConfigMapper chatConfigMapper; private final ChatConfigMapper chatConfigMapper;
public ChatConfigRepositoryImpl(ChatConfigUtils chatConfigUtils, public ChatConfigRepositoryImpl(ChatConfigUtils chatConfigUtils,
ChatConfigMapper chatConfigMapper) { ChatConfigMapper chatConfigMapper) {
this.chatConfigUtils = chatConfigUtils; this.chatConfigUtils = chatConfigUtils;
this.chatConfigMapper = chatConfigMapper; this.chatConfigMapper = chatConfigMapper;
} }
@@ -32,8 +32,8 @@ public class ChatConfigRepositoryImpl implements ChatConfigRepository {
@Override @Override
public Long createConfig(ChatConfig chaConfig) { public Long createConfig(ChatConfig chaConfig) {
ChatConfigDO chaConfigDO = chatConfigUtils.chatConfig2DO(chaConfig); ChatConfigDO chaConfigDO = chatConfigUtils.chatConfig2DO(chaConfig);
chatConfigMapper.addConfig(chaConfigDO);
return chatConfigMapper.addConfig(chaConfigDO); return chaConfigDO.getId();
} }
@Override @Override
@@ -45,26 +45,23 @@ public class ChatConfigRepositoryImpl implements ChatConfigRepository {
} }
@Override @Override
public List<ChatConfigInfo> getChatConfig(ChatConfigFilter filter) { public List<ChatConfigResp> getChatConfig(ChatConfigFilter filter) {
List<ChatConfigInfo> chaConfigDescriptorList = new ArrayList<>(); List<ChatConfigResp> chaConfigDescriptorList = new ArrayList<>();
ChatConfigFilterInternal filterInternal = new ChatConfigFilterInternal(); ChatConfigFilterInternal filterInternal = new ChatConfigFilterInternal();
BeanUtils.copyProperties(filter, filterInternal); BeanUtils.copyProperties(filter, filterInternal);
filterInternal.setStatus(filter.getStatus().getCode()); filterInternal.setStatus(filter.getStatus().getCode());
List<ChatConfigDO> chaConfigDOList = chatConfigMapper.search(filterInternal); List<ChatConfigDO> chaConfigDOList = chatConfigMapper.search(filterInternal);
if (!CollectionUtils.isEmpty(chaConfigDOList)) { if (!CollectionUtils.isEmpty(chaConfigDOList)) {
chaConfigDOList.stream().forEach(chaConfigDO -> chaConfigDOList.stream().forEach(chaConfigDO ->
chaConfigDescriptorList.add(chatConfigUtils.chatConfigDO2Descriptor(chaConfigDO))); chaConfigDescriptorList.add(chatConfigUtils.chatConfigDO2Descriptor(chaConfigDO.getDomainId(), chaConfigDO)));
} }
return chaConfigDescriptorList; return chaConfigDescriptorList;
} }
@Override @Override
public ChatConfigInfo getConfigByDomainId(Long domainId) { public ChatConfigResp getConfigByDomainId(Long domainId) {
ChatConfigDO chaConfigPO = chatConfigMapper.fetchConfigByDomainId(domainId); ChatConfigDO chaConfigPO = chatConfigMapper.fetchConfigByDomainId(domainId);
if (Objects.isNull(chaConfigPO)) { return chatConfigUtils.chatConfigDO2Descriptor(domainId, chaConfigPO);
return new ChatConfigInfo();
}
return chatConfigUtils.chatConfigDO2Descriptor(chaConfigPO);
} }
} }

View File

@@ -1,7 +1,6 @@
package com.tencent.supersonic.chat.infrastructure.semantic; package com.tencent.supersonic.chat.infrastructure.semantic;
import com.tencent.supersonic.chat.application.ConfigServiceImpl; import com.tencent.supersonic.chat.application.ConfigServiceImpl;
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
import lombok.Data; import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@@ -24,12 +23,21 @@ public class DefaultSemanticConfig {
@Value("${fetchDomainSchemaPath.path:/api/semantic/schema}") @Value("${fetchDomainSchemaPath.path:/api/semantic/schema}")
private String fetchDomainSchemaPath; private String fetchDomainSchemaPath;
@Autowired @Value("${fetchDomainList.path:/api/semantic/schema/dimension/page}")
private DefaultSemanticInternalUtils defaultSemanticInternalUtils; private String fetchDimensionPagePath;
@Value("${fetchDomainList.path:/api/semantic/schema/metric/page}")
private String fetchMetricPagePath;
@Value("${fetchDomainList.path:/api/semantic/schema/domain/list}")
private String fetchDomainListPath;
@Value("${fetchDomainList.path:/api/semantic/schema/domain/view/list}")
private String fetchDomainViewListPath;
@Autowired @Autowired
private RestTemplate restTemplate; private RestTemplate restTemplate;
@Autowired @Autowired
private ConfigServiceImpl chaConfigService; private ConfigServiceImpl configService;
} }

View File

@@ -1,20 +1,27 @@
package com.tencent.supersonic.chat.infrastructure.semantic; package com.tencent.supersonic.chat.infrastructure.semantic;
import com.github.pagehelper.PageInfo;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.component.SemanticLayer; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatAggConfig;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatDetailConfig;
import com.tencent.supersonic.chat.domain.pojo.config.ItemVisibility; import com.tencent.supersonic.chat.domain.pojo.config.ItemVisibility;
import com.tencent.supersonic.common.util.context.ContextUtils; import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import com.tencent.supersonic.common.util.context.ThreadContext;
import com.tencent.supersonic.common.util.json.JsonUtil; import com.tencent.supersonic.common.util.json.JsonUtil;
import com.tencent.supersonic.semantic.api.core.request.DomainSchemaFilterReq; import com.tencent.supersonic.semantic.api.core.request.DomainSchemaFilterReq;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp; import com.tencent.supersonic.semantic.api.core.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.core.response.*;
import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp;
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq; import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq; import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
import com.tencent.supersonic.semantic.core.domain.DimensionService;
import com.tencent.supersonic.semantic.core.domain.DomainService;
import com.tencent.supersonic.semantic.core.domain.MetricService;
import com.tencent.supersonic.semantic.query.domain.SchemaService; import com.tencent.supersonic.semantic.query.domain.SchemaService;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -30,8 +37,21 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
private static final Cache<String, List<DomainSchemaResp>> domainSchemaCache = private static final Cache<String, List<DomainSchemaResp>> domainSchemaCache =
CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build(); CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
private SchemaService schemaService; private SchemaService schemaService;
private S2ThreadContext s2ThreadContext;
private DomainService domainService;
private DimensionService dimensionService;
private MetricService metricService;
// public LocalSemanticLayerImpl(DomainService domainService){
// this.domainService=domainService;
// }
@Override @Override
public QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user) { public QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user) {
deletionDuplicated(queryStructReq); deletionDuplicated(queryStructReq);
@@ -60,6 +80,7 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
return null; return null;
} }
public List<DomainSchemaResp> fetchDomainSchemaAll(List<Long> ids) { public List<DomainSchemaResp> fetchDomainSchemaAll(List<Long> ids) {
DomainSchemaFilterReq filter = new DomainSchemaFilterReq(); DomainSchemaFilterReq filter = new DomainSchemaFilterReq();
@@ -71,23 +92,23 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
@SneakyThrows @SneakyThrows
public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids) { public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids, Boolean cacheEnable) {
// return domainSchemaCache.get(String.valueOf(ids), () -> { if (cacheEnable) {
// List<DomainSchemaResp> data = fetchDomainSchemaAll(ids); return domainSchemaCache.get(String.valueOf(ids), () -> {
// fillEntityNameAndFilterBlackElement(data); List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
// return data; fillEntityNameAndFilterBlackElement(data);
// }); return data;
});
}
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids); List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
fillEntityNameAndFilterBlackElement(data); fillEntityNameAndFilterBlackElement(data);
return data; return data;
} }
@Override public DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable) {
public DomainSchemaResp getDomainSchemaInfo(Long domain) {
List<Long> ids = new ArrayList<>(); List<Long> ids = new ArrayList<>();
ids.add(domain); ids.add(domain);
List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids); List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids, cacheEnable);
if (!CollectionUtils.isEmpty(domainSchemaResps)) { if (!CollectionUtils.isEmpty(domainSchemaResps)) {
Optional<DomainSchemaResp> domainSchemaResp = domainSchemaResps.stream() Optional<DomainSchemaResp> domainSchemaResp = domainSchemaResps.stream()
.filter(d -> d.getId().equals(domain)).findFirst(); .filter(d -> d.getId().equals(domain)).findFirst();
@@ -101,21 +122,21 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
@Override @Override
public List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids) { public List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids) {
return fetchDomainSchema(ids); return fetchDomainSchema(ids, true);
} }
public DomainSchemaResp fillEntityNameAndFilterBlackElement(DomainSchemaResp domainSchemaResp) { public DomainSchemaResp fillEntityNameAndFilterBlackElement(DomainSchemaResp domainSchemaResp) {
if (Objects.isNull(domainSchemaResp) || Objects.isNull(domainSchemaResp.getId())) { if (Objects.isNull(domainSchemaResp) || Objects.isNull(domainSchemaResp.getId())) {
return domainSchemaResp; return domainSchemaResp;
} }
ChatConfigInfo chaConfigInfo = getConfigBaseInfo(domainSchemaResp.getId()); ChatConfigResp chatConfigResp = getConfigBaseInfo(domainSchemaResp.getId());
// fill entity names // fill entity names
fillEntityNamesInfo(domainSchemaResp, chaConfigInfo); fillEntityNamesInfo(domainSchemaResp, chatConfigResp);
// filter black element // filter black element
filterBlackDim(domainSchemaResp, chaConfigInfo); filterBlackDim(domainSchemaResp, chatConfigResp);
filterBlackMetric(domainSchemaResp, chaConfigInfo); filterBlackMetric(domainSchemaResp, chatConfigResp);
return domainSchemaResp; return domainSchemaResp;
} }
@@ -126,9 +147,9 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
} }
} }
private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigInfo chaConfigInfo) { private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigResp) {
ItemVisibility visibility = chaConfigInfo.getVisibility(); ItemVisibility visibility = generateFinalVisibility(chatConfigResp);
if (Objects.nonNull(chaConfigInfo) && Objects.nonNull(visibility) if (Objects.nonNull(chatConfigResp) && Objects.nonNull(visibility)
&& !CollectionUtils.isEmpty(visibility.getBlackMetricIdList()) && !CollectionUtils.isEmpty(visibility.getBlackMetricIdList())
&& !CollectionUtils.isEmpty(domainSchemaResp.getMetrics())) { && !CollectionUtils.isEmpty(domainSchemaResp.getMetrics())) {
List<MetricSchemaResp> metric4Chat = domainSchemaResp.getMetrics().stream() List<MetricSchemaResp> metric4Chat = domainSchemaResp.getMetrics().stream()
@@ -138,9 +159,32 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
} }
} }
private void filterBlackDim(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) { private ItemVisibility generateFinalVisibility(ChatConfigResp chatConfigInfo) {
ItemVisibility visibility = chatConfigInfo.getVisibility(); ItemVisibility visibility = new ItemVisibility();
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(visibility)
ChatAggConfig chatAggConfig = chatConfigInfo.getChatAggConfig();
ChatDetailConfig chatDetailConfig = chatConfigInfo.getChatDetailConfig();
// both black is exist
if (Objects.nonNull(chatAggConfig) && Objects.nonNull(chatAggConfig.getVisibility())
&& Objects.nonNull(chatDetailConfig) && Objects.nonNull(chatDetailConfig.getVisibility())) {
List<Long> blackDimIdList = new ArrayList<>();
blackDimIdList.addAll(chatAggConfig.getVisibility().getBlackDimIdList());
blackDimIdList.retainAll(chatDetailConfig.getVisibility().getBlackDimIdList());
List<Long> blackMetricIdList = new ArrayList<>();
blackMetricIdList.addAll(chatAggConfig.getVisibility().getBlackMetricIdList());
blackMetricIdList.retainAll(chatDetailConfig.getVisibility().getBlackMetricIdList());
visibility.setBlackDimIdList(blackDimIdList);
visibility.setBlackMetricIdList(blackMetricIdList);
}
return visibility;
}
private void filterBlackDim(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigResp) {
ItemVisibility visibility = generateFinalVisibility(chatConfigResp);
if (Objects.nonNull(chatConfigResp) && Objects.nonNull(visibility)
&& !CollectionUtils.isEmpty(visibility.getBlackDimIdList()) && !CollectionUtils.isEmpty(visibility.getBlackDimIdList())
&& !CollectionUtils.isEmpty(domainSchemaResp.getDimensions())) { && !CollectionUtils.isEmpty(domainSchemaResp.getDimensions())) {
List<DimSchemaResp> dim4Chat = domainSchemaResp.getDimensions().stream() List<DimSchemaResp> dim4Chat = domainSchemaResp.getDimensions().stream()
@@ -150,10 +194,11 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
} }
} }
private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) { private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigResp) {
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getEntity()) if (Objects.nonNull(chatConfigResp) && Objects.nonNull(chatConfigResp.getChatDetailConfig())
&& !CollectionUtils.isEmpty(chatConfigInfo.getEntity().getNames())) { && Objects.nonNull(chatConfigResp.getChatDetailConfig().getEntity())
domainSchemaResp.setEntityNames(chatConfigInfo.getEntity().getNames()); && !CollectionUtils.isEmpty(chatConfigResp.getChatDetailConfig().getEntity().getNames())) {
domainSchemaResp.setEntityNames(chatConfigResp.getChatDetailConfig().getEntity().getNames());
} }
} }
@@ -173,9 +218,37 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
} }
} }
public ChatConfigInfo getConfigBaseInfo(Long domain) { public ChatConfigResp getConfigBaseInfo(Long domain) {
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class); DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
return defaultSemanticConfig.getChaConfigService().fetchConfigByDomainId(domain); return defaultSemanticConfig.getConfigService().fetchConfigByDomainId(domain);
}
@Override
public List<DomainResp> getDomainListForViewer() {
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
ThreadContext threadContext = s2ThreadContext.get();
domainService = ContextUtils.getBean(DomainService.class);
return domainService.getDomainListForViewer(threadContext.getUserName());
}
@Override
public List<DomainResp> getDomainListForAdmin() {
domainService = ContextUtils.getBean(DomainService.class);
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
ThreadContext threadContext = s2ThreadContext.get();
return domainService.getDomainListForAdmin(threadContext.getUserName());
}
@Override
public PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd) {
dimensionService = ContextUtils.getBean(DimensionService.class);
return dimensionService.queryDimension(pageDimensionCmd);
}
@Override
public PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd) {
metricService = ContextUtils.getBean(MetricService.class);
return metricService.queryMetric(pageMetricCmd);
} }
} }

View File

@@ -1,39 +1,40 @@
package com.tencent.supersonic.chat.infrastructure.semantic; package com.tencent.supersonic.chat.infrastructure.semantic;
import static com.tencent.supersonic.common.constant.Constants.TRUE_LOWER;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants; import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.chat.api.component.SemanticLayer; import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.application.ConfigServiceImpl;
import com.tencent.supersonic.chat.domain.pojo.config.*;
import com.tencent.supersonic.common.util.context.ContextUtils; import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import com.tencent.supersonic.common.util.context.ThreadContext;
import com.tencent.supersonic.common.util.json.JsonUtil;
import com.tencent.supersonic.semantic.api.core.request.DomainSchemaFilterReq; import com.tencent.supersonic.semantic.api.core.request.DomainSchemaFilterReq;
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp; import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp; import com.tencent.supersonic.semantic.api.core.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.core.response.*;
import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp;
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq; import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq; import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo;
import com.tencent.supersonic.chat.domain.pojo.config.ItemVisibility;
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
import com.tencent.supersonic.common.exception.CommonException; import com.tencent.supersonic.common.exception.CommonException;
import com.tencent.supersonic.common.result.ResultData; import com.tencent.supersonic.common.result.ResultData;
import com.tencent.supersonic.common.result.ReturnCode; import com.tencent.supersonic.common.result.ReturnCode;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@@ -41,11 +42,27 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import static com.tencent.supersonic.common.constant.Constants.*;
import static com.tencent.supersonic.common.constant.Constants.PAGESIZE_LOWER;
@Slf4j @Slf4j
public class RemoteSemanticLayerImpl implements SemanticLayer { public class RemoteSemanticLayerImpl implements SemanticLayer {
private RestTemplate restTemplate;
@Autowired
private ConfigServiceImpl configService;
@Autowired
private S2ThreadContext s2ThreadContext;
@Autowired
private AuthenticationConfig authenticationConfig;
private static final Cache<String, List<DomainSchemaResp>> domainSchemaCache = private static final Cache<String, List<DomainSchemaResp>> domainSchemaCache =
CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build(); CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
private ParameterizedTypeReference<ResultData<QueryResultWithSchemaResp>> structTypeRef = private ParameterizedTypeReference<ResultData<QueryResultWithSchemaResp>> structTypeRef =
@@ -70,11 +87,9 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
} }
public QueryResultWithSchemaResp searchByRestTemplate(String url, String jsonReq) { public QueryResultWithSchemaResp searchByRestTemplate(String url, String jsonReq) {
DefaultSemanticInternalUtils defaultSemanticInternalUtils = ContextUtils.getBean(
DefaultSemanticInternalUtils.class);
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
defaultSemanticInternalUtils.fillToken(headers); fillToken(headers);
URI requestUrl = UriComponentsBuilder.fromHttpUrl(url).build().encode().toUri(); URI requestUrl = UriComponentsBuilder.fromHttpUrl(url).build().encode().toUri();
HttpEntity<String> entity = new HttpEntity<>(jsonReq, headers); HttpEntity<String> entity = new HttpEntity<>(jsonReq, headers);
log.info("url:{},searchByRestTemplate:{}", url, entity.getBody()); log.info("url:{},searchByRestTemplate:{}", url, entity.getBody());
@@ -102,12 +117,10 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
} }
public List<DomainSchemaResp> fetchDomainSchemaAll(List<Long> ids) { public List<DomainSchemaResp> fetchDomainSchemaAll(List<Long> ids) {
DefaultSemanticInternalUtils defaultSemanticInternalUtils = ContextUtils.getBean(
DefaultSemanticInternalUtils.class);
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set(UserConstants.INTERNAL, TRUE_LOWER); headers.set(UserConstants.INTERNAL, TRUE_LOWER);
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
defaultSemanticInternalUtils.fillToken(headers); fillToken(headers);
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class); DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
URI requestUrl = UriComponentsBuilder.fromHttpUrl( URI requestUrl = UriComponentsBuilder.fromHttpUrl(
@@ -139,19 +152,24 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
@SneakyThrows @SneakyThrows
public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids) { public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids, Boolean cacheEnable) {
return domainSchemaCache.get(String.valueOf(ids), () -> { if (cacheEnable) {
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids); return domainSchemaCache.get(String.valueOf(ids), () -> {
fillEntityNameAndFilterBlackElement(data); List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
return data; fillEntityNameAndFilterBlackElement(data);
}); return data;
});
}
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
fillEntityNameAndFilterBlackElement(data);
return data;
} }
@Override @Override
public DomainSchemaResp getDomainSchemaInfo(Long domain) { public DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable) {
List<Long> ids = new ArrayList<>(); List<Long> ids = new ArrayList<>();
ids.add(domain); ids.add(domain);
List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids); List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids, cacheEnable);
if (!CollectionUtils.isEmpty(domainSchemaResps)) { if (!CollectionUtils.isEmpty(domainSchemaResps)) {
Optional<DomainSchemaResp> domainSchemaResp = domainSchemaResps.stream() Optional<DomainSchemaResp> domainSchemaResp = domainSchemaResps.stream()
.filter(d -> d.getId().equals(domain)).findFirst(); .filter(d -> d.getId().equals(domain)).findFirst();
@@ -165,21 +183,21 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
@Override @Override
public List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids) { public List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids) {
return fetchDomainSchema(ids); return fetchDomainSchema(ids, true);
} }
public DomainSchemaResp fillEntityNameAndFilterBlackElement(DomainSchemaResp domainSchemaResp) { public DomainSchemaResp fillEntityNameAndFilterBlackElement(DomainSchemaResp domainSchemaResp) {
if (Objects.isNull(domainSchemaResp) || Objects.isNull(domainSchemaResp.getId())) { if (Objects.isNull(domainSchemaResp) || Objects.isNull(domainSchemaResp.getId())) {
return domainSchemaResp; return domainSchemaResp;
} }
ChatConfigInfo chaConfigInfo = getConfigBaseInfo(domainSchemaResp.getId()); ChatConfigResp chaConfigInfo = getConfigBaseInfo(domainSchemaResp.getId());
// fill entity names // fill entity names
fillEntityNamesInfo(domainSchemaResp, chaConfigInfo); fillEntityNamesInfo(domainSchemaResp, chaConfigInfo);
// filter black element // filter black element
filterBlackDim(domainSchemaResp, chaConfigInfo); filterBlackDim(domainSchemaResp, chaConfigInfo);
filterBlackMetric(domainSchemaResp, chaConfigInfo); filterBlackMetric(domainSchemaResp, chaConfigInfo);
return domainSchemaResp; return domainSchemaResp;
} }
@@ -190,8 +208,9 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
} }
} }
private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigInfo chaConfigInfo) { private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigResp chaConfigInfo) {
ItemVisibility visibility = chaConfigInfo.getVisibility();
ItemVisibility visibility = generateFinalVisibility(chaConfigInfo);
if (Objects.nonNull(chaConfigInfo) && Objects.nonNull(visibility) if (Objects.nonNull(chaConfigInfo) && Objects.nonNull(visibility)
&& !CollectionUtils.isEmpty(visibility.getBlackMetricIdList()) && !CollectionUtils.isEmpty(visibility.getBlackMetricIdList())
&& !CollectionUtils.isEmpty(domainSchemaResp.getMetrics())) { && !CollectionUtils.isEmpty(domainSchemaResp.getMetrics())) {
@@ -202,8 +221,31 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
} }
} }
private void filterBlackDim(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) { private ItemVisibility generateFinalVisibility(ChatConfigResp chatConfigInfo) {
ItemVisibility visibility = chatConfigInfo.getVisibility(); ItemVisibility visibility = new ItemVisibility();
ChatAggConfig chatAggConfig = chatConfigInfo.getChatAggConfig();
ChatDetailConfig chatDetailConfig = chatConfigInfo.getChatDetailConfig();
// both black is exist
if (Objects.nonNull(chatAggConfig) && Objects.nonNull(chatAggConfig.getVisibility())
&& Objects.nonNull(chatDetailConfig) && Objects.nonNull(chatDetailConfig.getVisibility())) {
List<Long> blackDimIdList = new ArrayList<>();
blackDimIdList.addAll(chatAggConfig.getVisibility().getBlackDimIdList());
blackDimIdList.retainAll(chatDetailConfig.getVisibility().getBlackDimIdList());
List<Long> blackMetricIdList = new ArrayList<>();
blackMetricIdList.addAll(chatAggConfig.getVisibility().getBlackMetricIdList());
blackMetricIdList.retainAll(chatDetailConfig.getVisibility().getBlackMetricIdList());
visibility.setBlackDimIdList(blackDimIdList);
visibility.setBlackMetricIdList(blackMetricIdList);
}
return visibility;
}
private void filterBlackDim(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigInfo) {
ItemVisibility visibility = generateFinalVisibility(chatConfigInfo);
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(visibility) if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(visibility)
&& !CollectionUtils.isEmpty(visibility.getBlackDimIdList()) && !CollectionUtils.isEmpty(visibility.getBlackDimIdList())
&& !CollectionUtils.isEmpty(domainSchemaResp.getDimensions())) { && !CollectionUtils.isEmpty(domainSchemaResp.getDimensions())) {
@@ -214,10 +256,11 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
} }
} }
private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) { private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigInfo) {
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getEntity()) if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getChatDetailConfig())
&& !CollectionUtils.isEmpty(chatConfigInfo.getEntity().getNames())) { && Objects.nonNull(chatConfigInfo.getChatDetailConfig().getEntity())
domainSchemaResp.setEntityNames(chatConfigInfo.getEntity().getNames()); && !CollectionUtils.isEmpty(chatConfigInfo.getChatDetailConfig().getEntity().getNames())) {
domainSchemaResp.setEntityNames(chatConfigInfo.getChatDetailConfig().getEntity().getNames());
} }
} }
@@ -237,9 +280,102 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
} }
} }
public ChatConfigInfo getConfigBaseInfo(Long domain) { public ChatConfigResp getConfigBaseInfo(Long domain) {
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class); DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
return defaultSemanticConfig.getChaConfigService().fetchConfigByDomainId(domain); return defaultSemanticConfig.getConfigService().fetchConfigByDomainId(domain);
}
@Override
public List<DomainResp> getDomainListForViewer() {
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
Object domainDescListObject = fetchHttpResult(defaultSemanticConfig.getSemanticUrl() + defaultSemanticConfig.getFetchDomainViewListPath(), null, HttpMethod.GET);
List<DomainResp> domainDescList = JsonUtil.toList(JsonUtil.toString(domainDescListObject), DomainResp.class);
return domainDescList;
}
@Override
public List<DomainResp> getDomainListForAdmin() {
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
Object domainDescListObject = fetchHttpResult(defaultSemanticConfig.getSemanticUrl() + defaultSemanticConfig.getFetchDomainListPath(), null, HttpMethod.GET);
List<DomainResp> domainDescList = JsonUtil.toList(JsonUtil.toString(domainDescListObject), DomainResp.class);
return domainDescList;
}
public Object fetchHttpResult(String url, String bodyJson, HttpMethod httpMethod) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
fillToken(headers);
URI requestUrl = UriComponentsBuilder.fromHttpUrl(url).build().encode().toUri();
ParameterizedTypeReference<ResultData<Object>> responseTypeRef =
new ParameterizedTypeReference<ResultData<Object>>() {
};
HttpEntity<String> entity = new HttpEntity<>(JsonUtil.toString(bodyJson), headers);
try {
restTemplate = ContextUtils.getBean(RestTemplate.class);
ResponseEntity<ResultData<Object>> responseEntity = restTemplate.exchange(requestUrl,
httpMethod, entity, responseTypeRef);
ResultData<Object> responseBody = responseEntity.getBody();
log.debug("ApiResponse<fetchDomainSchema> responseBody:{}", responseBody);
if (ReturnCode.SUCCESS.getCode() == responseBody.getCode()) {
Object data = responseBody.getData();
return data;
}
} catch (Exception e) {
throw new RuntimeException("fetchDomainSchema interface error", e);
}
throw new RuntimeException("fetchDomainSchema interface error");
}
public void fillToken(HttpHeaders headers) {
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
authenticationConfig = ContextUtils.getBean(AuthenticationConfig.class);
ThreadContext threadContext = s2ThreadContext.get();
if (Objects.nonNull(threadContext) && Strings.isNotEmpty(threadContext.getToken())) {
if (Objects.nonNull(authenticationConfig) && Strings.isNotEmpty(
authenticationConfig.getTokenHttpHeaderKey())) {
headers.set(authenticationConfig.getTokenHttpHeaderKey(), threadContext.getToken());
}
} else {
log.debug("threadContext is null:{}", Objects.isNull(threadContext));
}
}
@Override
public PageInfo<MetricResp> queryMetricPage(PageMetricReq pageMetricCmd) {
String body = JsonUtil.toString(pageMetricCmd);
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
log.info("url:{}", defaultSemanticConfig.getSemanticUrl() + defaultSemanticConfig.getFetchMetricPagePath());
Object dimensionListObject = fetchHttpResult(defaultSemanticConfig.getSemanticUrl() + defaultSemanticConfig.getFetchMetricPagePath(), body, HttpMethod.POST);
LinkedHashMap map = (LinkedHashMap) dimensionListObject;
PageInfo<Object> metricDescObjectPageInfo = generatePageInfo(map);
PageInfo<MetricResp> metricDescPageInfo = new PageInfo<>();
BeanUtils.copyProperties(metricDescObjectPageInfo, metricDescPageInfo);
metricDescPageInfo.setList(metricDescPageInfo.getList());
return metricDescPageInfo;
}
@Override
public PageInfo<DimensionResp> queryDimensionPage(PageDimensionReq pageDimensionCmd) {
String body = JsonUtil.toString(pageDimensionCmd);
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
Object dimensionListObject = fetchHttpResult(defaultSemanticConfig.getSemanticUrl() + defaultSemanticConfig.getFetchDimensionPagePath(), body, HttpMethod.POST);
LinkedHashMap map = (LinkedHashMap) dimensionListObject;
PageInfo<Object> dimensionDescObjectPageInfo = generatePageInfo(map);
PageInfo<DimensionResp> dimensionDescPageInfo = new PageInfo<>();
BeanUtils.copyProperties(dimensionDescObjectPageInfo, dimensionDescPageInfo);
dimensionDescPageInfo.setList(dimensionDescPageInfo.getList());
return dimensionDescPageInfo;
}
private PageInfo<Object> generatePageInfo(LinkedHashMap map) {
PageInfo<Object> pageInfo = new PageInfo<>();
pageInfo.setList((List<Object>) map.get(LIST_LOWER));
Integer total = (Integer) map.get(TOTAL_LOWER);
pageInfo.setTotal(total);
Integer pageSize = (Integer) map.get(PAGESIZE_LOWER);
pageInfo.setPageSize(pageSize);
pageInfo.setPages((int) Math.ceil((double) total / pageSize));
return pageInfo;
} }
} }

View File

@@ -3,18 +3,19 @@ package com.tencent.supersonic.chat.rest;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder; import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.component.SemanticLayer;
import com.tencent.supersonic.chat.domain.utils.ComponentFactory;
import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq; import com.tencent.supersonic.semantic.api.core.request.PageDimensionReq;
import com.tencent.supersonic.semantic.api.core.request.PageMetricReq; import com.tencent.supersonic.semantic.api.core.request.PageMetricReq;
import com.tencent.supersonic.semantic.api.core.response.DimensionResp; import com.tencent.supersonic.semantic.api.core.response.DimensionResp;
import com.tencent.supersonic.semantic.api.core.response.DomainResp; import com.tencent.supersonic.semantic.api.core.response.DomainResp;
import com.tencent.supersonic.semantic.api.core.response.MetricResp; import com.tencent.supersonic.semantic.api.core.response.MetricResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBase; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBaseReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReq; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReqReq;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigFilter;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import com.tencent.supersonic.chat.domain.service.ConfigService; import com.tencent.supersonic.chat.domain.service.ConfigService;
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -37,43 +38,43 @@ public class ChatConfigController {
@Autowired @Autowired
private ConfigService configService; private ConfigService configService;
@Autowired
private DefaultSemanticInternalUtils defaultSemanticUtils; private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
@PostMapping @PostMapping
public Long addChatConfig(@RequestBody ChatConfigBase extendBaseCmd, public Long addChatConfig(@RequestBody ChatConfigBaseReq extendBaseCmd,
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
User user = UserHolder.findUser(request, response); User user = UserHolder.findUser(request, response);
return configService.addConfig(extendBaseCmd, user); return configService.addConfig(extendBaseCmd, user);
} }
@PutMapping @PutMapping
public Long editDomainExtend(@RequestBody ChatConfigEditReq extendEditCmd, public Long editDomainExtend(@RequestBody ChatConfigEditReqReq extendEditCmd,
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
User user = UserHolder.findUser(request, response); User user = UserHolder.findUser(request, response);
return configService.editConfig(extendEditCmd, user); return configService.editConfig(extendEditCmd, user);
} }
@PostMapping("/search") @PostMapping("/search")
public List<ChatConfigInfo> search(@RequestBody ChatConfigFilter filter, public List<ChatConfigResp> search(@RequestBody ChatConfigFilter filter,
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
User user = UserHolder.findUser(request, response); User user = UserHolder.findUser(request, response);
return configService.search(filter, user); return configService.search(filter, user);
} }
@GetMapping("/richDesc/{domainId}") @GetMapping("/richDesc/{domainId}")
public ChatConfigRichInfo getDomainExtendRichInfo(@PathVariable("domainId") Long domainId) { public ChatConfigRichResp getDomainExtendRichInfo(@PathVariable("domainId") Long domainId) {
return configService.getConfigRichInfo(domainId); return configService.getConfigRichInfo(domainId);
} }
@GetMapping("/richDesc/all") @GetMapping("/richDesc/all")
public List<ChatConfigRichInfo> getAllChatRichConfig() { public List<ChatConfigRichResp> getAllChatRichConfig() {
return configService.getAllChatRichConfig(); return configService.getAllChatRichConfig();
} }
@@ -85,23 +86,29 @@ public class ChatConfigController {
*/ */
@GetMapping("/domainList") @GetMapping("/domainList")
public List<DomainResp> getDomainList() { public List<DomainResp> getDomainList() {
return defaultSemanticUtils.getDomainListForAdmin();
return semanticLayer.getDomainListForAdmin();
//return defaultSemanticUtils.getDomainListForAdmin();
}
@GetMapping("/domainList/view")
public List<DomainResp> getDomainListForViewer() {
return semanticLayer.getDomainListForViewer();
//return defaultSemanticUtils.getDomainListForViewer();
} }
@PostMapping("/dimension/page") @PostMapping("/dimension/page")
public PageInfo<DimensionResp> queryDimension(@RequestBody PageDimensionReq pageDimensionCmd, public PageInfo<DimensionResp> queryDimension(@RequestBody PageDimensionReq pageDimensionCmd,
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
User user = UserHolder.findUser(request, response); return semanticLayer.queryDimensionPage(pageDimensionCmd);
return defaultSemanticUtils.queryDimensionPage(pageDimensionCmd, user);
} }
@PostMapping("/metric/page") @PostMapping("/metric/page")
public PageInfo<MetricResp> queryMetric(@RequestBody PageMetricReq pageMetrricCmd, public PageInfo<MetricResp> queryMetric(@RequestBody PageMetricReq pageMetrricCmd,
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
User user = UserHolder.findUser(request, response); return semanticLayer.queryMetricPage(pageMetrricCmd);
return defaultSemanticUtils.queryMetricPage(pageMetrricCmd, user);
} }

View File

@@ -0,0 +1,10 @@
# python path
export python_path="/usr/local/bin/python3.9"
# pip path
export pip_path="/usr/local/bin/pip3.9"
# host
export llm_host="127.0.0.1"
# port
export llm_port=9092
# start name
export start_name=api_service

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
binDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $binDir/../)
echo $binDir
source ${binDir}/env.sh
${pip_path} install -r $baseDir/requirements.txt
if ${python_path} -c "import langchain,fastapi,chromadb,tiktoken,uvicorn" >/dev/null 2>&1
then
echo "install ok, will pass"
else
if [ $? -eq 0 ]; then
echo "install ok"
else
echo "install fail ,pls check your install error log. cmd is : "
echo ${pip_path} install -r $baseDir/requirements.txt
exit 1
fi
fi

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
llm_host=$1
llm_port=$2
binDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $binDir/../)
source ${baseDir}/bin/env.sh
if [ "${llm_host}" = "" ] || [ "${llm_port}" = "" ]
then
echo "llm_host llm_port is not set"
exit 1
fi
if [ "${python_path}" = "" ] || [ "${pip_path}" = "" ]
then
echo "please set env value python_path , pip_path to python, pip path by export cmd "
exit 1
fi
chmod +x $binDir/install.sh
$binDir/install.sh
if [ $? -ne 0 ]; then
exit 1
fi
cd $baseDir/llm
nohup ${python_path} -m uvicorn ${start_name}:app --port ${llm_port} --host ${llm_host} > $baseDir/llm.log 2>&1 &

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
binDir=$(cd "$(dirname "$0")"; pwd)
baseDir=$(readlink -f $binDir/../)
source ${baseDir}/bin/env.sh
command=$1
function start()
{
pid=$(ps aux |grep ${start_name} | grep -v grep )
if [[ "$pid" == "" ]]; then
$baseDir/bin/run.sh && echo "Process started."
return 0
else
echo "Process (PID = $pid) is running."
return 1
fi
}
function stop()
{
pid=$(ps aux | grep ${start_name} | grep -v grep | awk '{print $2}')
if [[ "$pid" == "" ]]; then
echo "Process is not running !"
return 1
else
kill -9 $pid
echo "Process (PID = $pid) is killed !"
return 0
fi
}
case "$command" in
start)
echo -e "Starting ${start_name}"
start
;;
stop)
echo -e "Stopping ${start_name}"
stop
;;
restart)
echo -e "Resetting ${start_name}E"
stop
start
;;
*)
echo "Use command {start|stop|status|restart} to run."
exit 1
esac
exit 0

View File

@@ -0,0 +1,33 @@
# -*- coding:utf-8 -*-
import os
import logging
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from typing import Any, Mapping
from fastapi import FastAPI, HTTPException
from sql.run import query2sql
app = FastAPI()
@app.post("/query2sql/")
async def din_query2sql(query_body: Mapping[str, Any]):
if 'queryText' not in query_body:
raise HTTPException(status_code=400,
detail="query_text is not in query_body")
else:
query_text = query_body['queryText']
if 'schema' not in query_body:
raise HTTPException(status_code=400, detail="schema is not in query_body")
else:
schema = query_body['schema']
resp = query2sql(query_text=query_text, schema=schema)
return resp

View File

@@ -0,0 +1,147 @@
examplars = [
{
"table_name": "内容库产品",
"fields_list": """["部门", "模块", "用户名", "访问次数", "访问人数", "访问时长"]""",
"question": "比较jerryjzhang和lexluo在内容库的访问次数",
"analysis": """让我们一步一步地思考。在问题“比较jerryjzhang和lexluo在内容库的访问次数“中我们被问
“比较jerryjzhang和lexluo”所以我们需要column=[用户名]
”内容库的访问次数“所以我们需要column=[访问次数]
基于table和columns可能的cell values 是 = ['jerryjzhang', 'lexluo']。""",
"schema_links": """["用户名", "访问次数", "'jerryjzhang'", "'lexluo'"]""",
"sql": """select 用户名, 访问次数 from 内容库产品 where 用户名 in ('jerryjzhang', 'lexluo')"""
},
{
"table_name": "内容库产品",
"fields_list": """["部门", "模块", "用户名", "访问次数", "访问人数", "访问时长"]""",
"question": "内容库近12个月访问人数 按部门",
"analysis": """让我们一步一步地思考。在问题“内容库近12个月访问人数 按部门“中,我们被问:
“内容库近12个月访问人数”所以我们需要column=[访问人数]
”按部门“所以我们需要column=[部门]
基于table和columns可能的cell values 是 = []。""",
"schema_links": """["访问人数", "部门"]""",
"sql": """select 部门, sum(访问人数) from 内容库产品 where 部门 group by 部门"""
},
{
"table_name": "内容库产品",
"fields_list": """["部门", "模块", "用户名", "访问次数", "访问人数", "访问时长"]""",
"question": "内容库内容合作部、生态业务部的访问时长",
"analysis": """让我们一步一步地思考。在问题“内容库内容合作部、生态业务部的访问时长“中,我们被问:
“访问时长”所以我们需要column=[访问时长]
”内容库内容合作部、生态业务部“所以我们需要column=[部门]
基于table和columns可能的cell values 是 = ['内容合作部', '生态业务部']。""",
"schema_links": """["访问时长", "部门", "'内容合作部'", "'生态业务部'"]""",
"sql": """select 部门, 访问时长 from 内容库产品 where 部门 in ('内容合作部', '生态业务部')"""
},
{
"table_name": "优选",
"fields_list": """['优选版权归属系', '付费模式', '结算播放份额', '付费用户结算播放份额']""",
"question": "近3天阔景系TME结算播放份额",
"analysis": """让我们一步一步地思考。在问题“近3天阔景系TME结算播放份额“中我们被问
“TME结算播放份额”所以我们需要column=[结算播放份额]
”阔景系“所以我们需要column=[优选版权归属系]
基于table和columns可能的cell values 是 = ['阔景系']。""",
"schema_links": """["结算播放份额", "优选版权归属系", "'阔景系'"]""",
"sql": """select 优选版权归属系, 结算播放份额 from 优选 where 优选版权归属系 in ('阔景系')"""
},
{
"table_name": "歌曲库",
"fields_list": """['是否音乐人歌曲', 'Q音歌曲ID', 'Q音歌曲MID', '歌曲名', '歌曲版本', '歌曲类型', '翻唱类型', 'TME歌曲ID', '是否优选窄口径歌曲', '是否优选宽口径歌曲', '结算播放量', '运营播放量', '付费用户结算播放量', '历史累计结算播放量', '运营搜播量', '结算搜播量', '运营完播量', '运营推播量', '近7日复播率', '日均搜播量']""",
"question": "对比近3天翻唱版和纯音乐的歌曲播放量",
"analysis": """让我们一步一步地思考。在问题“对比近3天翻唱版和纯音乐的歌曲播放量“中我们被问
“歌曲播放量”所以我们需要column=[结算播放量]
”翻唱版和纯音乐的歌曲“所以我们需要column=[歌曲类型]
基于table和columns可能的cell values 是 = ['翻唱版', '纯音乐']。""",
"schema_links": """["结算播放量", "歌曲类型", "'翻唱版'", "'纯音乐'"]""",
"sql": """select 歌曲类型, 结算播放量 from 歌曲库 where 歌曲类型 in ('翻唱版', '纯音乐')"""
},
{
"table_name": "艺人库",
"fields_list": """['上下架状态', '歌手名', '歌手等级', '歌手类型', '歌手来源', 'TME音乐人等级', '活跃区域', '年龄', '歌手才能', '歌手风格', '粉丝数', '抖音粉丝数', '网易粉丝数', '微博粉丝数', '网易歌曲数', '在架歌曲数', '网易分享数', '独占歌曲数', '网易在架歌曲评论数', '有播放量歌曲数']""",
"question": "对比一下陈卓璇、孟美岐、赖美云的粉丝数",
"analysis": """让我们一步一步地思考。在问题“对比一下陈卓璇、孟美岐、赖美云的粉丝数“中,我们被问:
“粉丝数”所以我们需要column=[粉丝数]
”陈卓璇、孟美岐、赖美云“所以我们需要column=[歌手名]
基于table和columns可能的cell values 是 = ['陈卓璇', '孟美岐', '赖美云']。""",
"schema_links": """["粉丝数", "歌手名", "'陈卓璇'", "'孟美岐'", "'赖美云'"]""",
"sql": """select 歌手名, 粉丝数 from 艺人库 where 歌手名 in ('陈卓璇', '孟美岐', '赖美云')"""
},
{
"table_name": "歌曲库",
"fields_list": """['歌曲名', '歌曲版本', '歌曲类型', 'TME歌曲ID', '是否优选窄口径歌曲', '是否优选宽口径歌曲', '是否音乐人歌曲', '网易歌曲ID', 'Q音歌曲ID', 'Q音歌曲MID', '结算播放量', '运营播放量', '分享量', '收藏量', '运营搜播量', '结算搜播量', '拉新用户数', '拉活用户数', '分享率', '结算播放份额']""",
"question": "播放量大于1万的歌曲有多少",
"analysis": """让我们一步一步地思考。在问题“播放量大于1万的歌曲有多少“中我们被问
“歌曲有多少”所以我们需要column=[歌曲名]
”播放量大于1万的“所以我们需要column=[结算播放量]
基于table和columns可能的cell values 是 = [10000]。""",
"schema_links": """["歌曲名", "结算播放量", 10000]""",
"sql": """select 歌曲名 from 歌曲库 where 结算播放量 > 10000"""
},
{
"table_name": "内容库产品",
"fields_list": """['用户名', '部门', '模块', '访问时长', '访问次数', '访问人数']""",
"question": "内容库访问时长小于1小时且来自内容合作部的用户是哪些",
"analysis": """让我们一步一步地思考。在问题“内容库访问时长小于1小时且来自内容合作部的用户是哪些“中我们被问
“用户是哪些”所以我们需要column=[用户名]
”内容合作部的“所以我们需要column=[部门]
”访问时长小于1小时“所以我们需要column=[访问时长]
基于table和columns可能的cell values 是 = ['内容合作部', 1]。""",
"schema_links": """["用户名", "部门", "访问时长", "'内容合作部'", 1]""",
"sql": """select 用户名 from 内容库产品 where 部门 = '内容合作部' and 访问时长 < 1"""
},
{
"table_name": "内容库产品",
"fields_list": """['用户名', '部门', '模块', '访问次数', '访问人数', '访问时长']""",
"question": "内容库pv最高的用户有哪些",
"analysis": """让我们一步一步地思考。在问题“内容库pv最高的用户有哪些“中我们被问
“用户有哪些”所以我们需要column=[用户名]
”pv最高的“所以我们需要column=[访问次数]
基于table和columns可能的cell values 是 = []。""",
"schema_links": """["用户名", "访问次数"]""",
"sql": """select 用户名 from 内容库产品 order by 访问次数 desc limit 10"""
},
{
"table_name": "艺人库",
"fields_list": """['播放量层级', '播放量单调性', '播放量方差', '播放量突增类型', '播放量集中度', '歌手名', '歌手等级', '歌手类型', '歌手来源', 'TME音乐人等级', '结算播放量', '运营播放量', '历史累计结算播放量', '有播放量歌曲数', '历史累计运营播放量', '付费用户结算播放量', '结算播放量占比', '运营播放份额', '免费用户结算播放占比', '完播量']""",
"question": "近90天袁娅维播放量平均值是多少",
"analysis": """让我们一步一步地思考。在问题“近90天袁娅维播放量平均值是多少“中我们被问
“播放量平均值是多少”所以我们需要column=[结算播放量]
”袁娅维“所以我们需要column=[歌手名]
基于table和columns可能的cell values 是 = ['袁娅维']。""",
"schema_links": """["结算播放量", "歌手名", "'袁娅维'"]""",
"sql": """select avg(结算播放量) from 艺人库 where 歌手名 = '袁娅维'"""
},
{
"table_name": "艺人库",
"fields_list": """['播放量层级', '播放量单调性', '播放量方差', '播放量突增类型', '播放量集中度', '歌手名', '歌手等级', '歌手类型', '歌手来源', 'TME音乐人等级', '结算播放量', '历史累计结算播放量', '付费用户结算播放量', '结算播放量占比', '免费用户结算播放占比', '付费用户结算播放占比', '付费用户结算播放占比', '运营播放量', '有播放量歌曲数', '历史累计运营播放量']""",
"question": "周深近7天结算播放量总和是多少",
"analysis": """让我们一步一步地思考。在问题“周深近7天结算播放量总和是多少“中我们被问
“结算播放量总和是多少”所以我们需要column=[结算播放量]
”周深“所以我们需要column=[歌手名]
基于table和columns可能的cell values 是 = ['周深']。""",
"schema_links": """["结算播放量", "歌手名", "'周深'"]""",
"sql": """select sum(结算播放量) from 艺人库 where 歌手名 = '周深'"""
},
{
"table_name": "内容库产品",
"fields_list": """['部门', '模块', '用户名', '访问次数', '访问人数', '访问时长']""",
"question": "内容库访问次数大于1k的部门是哪些",
"analysis": """让我们一步一步地思考。在问题“内容库访问次数大于1k的部门是哪些“中我们被问
“部门是哪些”所以我们需要column=[部门]
”访问次数大于1k的“所以我们需要column=[访问次数]
基于table和columns可能的cell values 是 = [1000]。""",
"schema_links": """["部门", "访问次数", 1000]""",
"sql": """select 部门 from 内容库产品 where 访问次数 > 1000"""
},
{
"table_name": "歌曲库",
"fields_list": """['歌曲名', '歌手名' , '歌曲版本', '歌曲类型', 'TME歌曲ID', '是否优选窄口径歌曲', '是否优选宽口径歌曲', '是否音乐人歌曲', '网易歌曲ID', 'Q音歌曲ID', 'Q音歌曲MID', '结算播放量', '运营播放量', '分享量', '收藏量', '运营搜播量', '结算搜播量', '拉新用户数', '拉活用户数', '分享率', '结算播放份额']""",
"question": "陈奕迅唱的所有的播放量大于20k的孤勇者有哪些",
"analysis": """让我们一步一步地思考。在问题“陈奕迅唱的所有的播放量大于20k的孤勇者有哪些“中我们被问
“孤勇者有哪些”所以我们需要column=[歌曲名]
”播放量大于20k的“所以我们需要column=[结算播放量]
”陈奕迅唱的“所以我们需要column=[歌手名]
基于table和columns可能的cell values 是 = [20000, '陈奕迅']。""",
"schema_links": """["歌曲名", "结算播放量", "歌手名", 20000, "'陈奕迅'"]""",
"sql": """select 歌曲名 from 歌曲库 where 结算播放量 > 20000 and 歌手名 = '陈奕迅'"""
}
]

View File

@@ -0,0 +1,15 @@
# -*- coding:utf-8 -*-
import re
def schema_link_parse(schema_link_output):
try:
schema_link_output = schema_link_output.strip()
pattern = r'Schema_links:(.*)'
schema_link_output = re.findall(pattern, schema_link_output, re.DOTALL)[
0].strip()
except Exception as e:
print(e)
schema_link_output = None
return schema_link_output

View File

@@ -0,0 +1,88 @@
# -*- coding:utf-8 -*-
from typing import Any, List, Mapping, Optional, Union
import requests
import logging
import json
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from langchain.prompts import PromptTemplate
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.llms import OpenAI
from few_shot_example.sql_exampler import examplars
from output_parser import schema_link_parse
def schema_linking_prompt_maker(user_query: str, domain_name: str,
fields_list: List[str],
few_shots_example: str):
instruction = "# 根据数据库的表结构,找出为每个问题生成SQL查询语句的schema_links\n"
schema_linking_prompt = "Table {table_name}, columns = {fields_list}\n问题:{user_query}\n分析: 让我们一步一步地思考。".format(
table_name=domain_name,
fields_list=fields_list,
user_query=user_query)
return instruction + few_shots_example + schema_linking_prompt
def schema_linking_exampler(user_query: str,
domain_name: str,
fields_list: List[str]
) -> str:
example_prompt_template = PromptTemplate(
input_variables=["table_name", "fields_list", "question", "analysis",
"schema_links"],
template="Table {table_name}, columns = {fields_list}\n问题:{question}\n分析:{analysis} 所以Schema_links是:\nSchema_links:{schema_links}")
instruction = "# 根据数据库的表结构,找出为每个问题生成SQL查询语句的schema_links"
schema_linking_prompt = "Table {table_name}, columns = {fields_list}\n问题:{question}\n分析: 让我们一步一步地思考。"
schema_linking_example_prompt_template = FewShotPromptTemplate(
examples=examplars,
example_prompt=example_prompt_template,
example_separator="\n\n",
prefix=instruction,
input_variables=["table_name", "fields_list", "question"],
suffix=schema_linking_prompt
)
schema_linking_example_prompt = schema_linking_example_prompt_template.format(
table_name=domain_name,
fields_list=fields_list,
question=user_query)
return schema_linking_example_prompt
def sql_exampler(user_query: str,
domain_name: str,
schema_link_str: str
) -> str:
instruction = "# 根据schema_links为每个问题生成SQL查询语句"
sql_example_prompt_template = PromptTemplate(
input_variables=["question", "table_name", "schema_links", "sql"],
template="问题:{question}\nTable {table_name}\nSchema_links:{schema_links}\nSQL:{sql}")
sql_prompt = "问题:{question}\nTable {table_name}\nSchema_links:{schema_links}\nSQL:"
sql_example_prompt_template = FewShotPromptTemplate(
examples=examplars,
example_prompt=sql_example_prompt_template,
example_separator="\n\n",
prefix=instruction,
input_variables=["question", "table_name", "schema_links"],
suffix=sql_prompt
)
sql_example_prompt = sql_example_prompt_template.format(question=user_query,
table_name=domain_name,
schema_links=schema_link_str)
return sql_example_prompt

View File

@@ -0,0 +1,48 @@
# -*- coding:utf-8 -*-
from typing import List, Union
import logging
import json
import os
import sys
from langchain.llms import OpenAI
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from sql.prompt_maker import schema_linking_exampler, schema_link_parse, \
sql_exampler
MODEL_NAME = "gpt-3.5-turbo-16k"
OPENAI_API_KEY = "YOUR_API_KEY"
TEMPERATURE = 0.0
llm = OpenAI(openai_api_key=OPENAI_API_KEY, model_name=MODEL_NAME,
temperature=TEMPERATURE)
def query2sql(query_text: str, schema: dict):
print("schema: ", schema)
domain_name = schema['domainName']
fields_list = schema['fieldNameList']
schema_linking_prompt = schema_linking_exampler(query_text, domain_name,
fields_list)
schema_link_output = llm(schema_linking_prompt)
schema_link_str = schema_link_parse(schema_link_output)
sql_prompt = sql_exampler(query_text, domain_name, schema_link_str)
sql_output = llm(sql_prompt)
resp = dict()
resp['query'] = query_text
resp['domain'] = domain_name
resp['fields'] = fields_list
resp['schemaLinkingOutput'] = schema_link_output
resp['schemaLinkStr'] = schema_link_str
resp['sqlOutput'] = sql_output
return resp

View File

@@ -0,0 +1,8 @@
langchain==0.0.207
openai==0.27.4
fastapi==0.95.1
chromadb==0.3.21
tiktoken==0.3.3
uvicorn[standard]==0.21.1

View File

@@ -9,10 +9,8 @@
type="com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO"> type="com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="domain_id" property="domainId"/> <result column="domain_id" property="domainId"/>
<result column="default_metrics" property="defaultMetrics"/> <result column="chat_detail_config" property="chatDetailConfig"/>
<result column="visibility" property="visibility"/> <result column="chat_agg_config" property="chatAggConfig"/>
<result column="entity_info" property="entity"/>
<result column="dictionary_info" property="knowledgeInfo"/>
<result column="status" property="status"/> <result column="status" property="status"/>
<result column="created_by" property="createdBy"/> <result column="created_by" property="createdBy"/>
<result column="updated_by" property="updatedBy"/> <result column="updated_by" property="updatedBy"/>
@@ -25,11 +23,11 @@
useGeneratedKeys="true" keyProperty="id"> useGeneratedKeys="true" keyProperty="id">
insert into s2_chat_config insert into s2_chat_config
( (
domain_id, `default_metrics`, visibility, entity_info, dictionary_info, status, created_by, updated_by, created_at, updated_at domain_id, `chat_detail_config`, chat_agg_config, status, created_by, updated_by, created_at, updated_at
) )
values values
( (
#{domainId}, #{defaultMetrics}, #{visibility}, #{entity}, #{knowledgeInfo}, #{status}, #{createdBy}, #{updatedBy}, #{createdAt}, #{updatedAt} #{domainId}, #{chatDetailConfig}, #{chatAggConfig}, #{status}, #{createdBy}, #{updatedBy}, #{createdAt}, #{updatedAt}
) )
</insert> </insert>
@@ -38,18 +36,11 @@
update s2_chat_config update s2_chat_config
<set> <set>
`updated_at` = #{updatedAt} , `updated_at` = #{updatedAt} ,
<if test="chatDetailConfig != null and chatDetailConfig != ''">
<if test="defaultMetrics != null and defaultMetrics != ''"> `chat_detail_config` = #{chatDetailConfig} ,
`default_metrics` = #{defaultMetrics} ,
</if> </if>
<if test="visibility != null and visibility != ''"> <if test="chatAggConfig != null and chatAggConfig != ''">
visibility = #{visibility} , chat_agg_config = #{chatAggConfig} ,
</if>
<if test="entity != null and entity != ''">
entity_info = #{entity} ,
</if>
<if test="knowledgeInfo != null and knowledgeInfo != ''">
`dictionary_info` = #{knowledgeInfo} ,
</if> </if>
<if test="status != null and status != ''"> <if test="status != null and status != ''">
status = #{status} , status = #{status} ,
@@ -90,7 +81,8 @@
select * select *
from s2_chat_config from s2_chat_config
where domain_id = #{domainId} where domain_id = #{domainId}
order by status and status != 3
order by updated_at desc
limit 1 limit 1
</select> </select>

View File

@@ -1,28 +0,0 @@
package com.tencent.supersonic.chat.domain.utils;
import com.tencent.supersonic.semantic.api.core.enums.TimeDimensionEnum;
import java.text.MessageFormat;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
/**
* @author lex luo
* @date 2023/6/29 16:05
*/
class DslToSemanticInfoTest {
@Test
void search() {
Integer domainId = 1;
String dayField = TimeDimensionEnum.DAY.getName();
String startDate = "2023-04-01";
String endDate = "2023-06-01";
String format = MessageFormat.format(DslToSemanticInfo.SUB_TABLE, domainId, dayField, startDate, endDate);
Assert.assertEquals(format,
" ( select * from t_1 where sys_imp_date >= '2023-04-01' and sys_imp_date <= '2023-06-01' ) as t_sub_1");
}
}

View File

@@ -13,8 +13,8 @@ import com.tencent.supersonic.semantic.api.core.response.DomainSchemaResp;
import com.tencent.supersonic.semantic.api.core.response.MetricResp; import com.tencent.supersonic.semantic.api.core.response.MetricResp;
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp; import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
import com.tencent.supersonic.chat.application.ConfigServiceImpl; import com.tencent.supersonic.chat.application.ConfigServiceImpl;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo; import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetric; import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetric;
import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetricInfo; import com.tencent.supersonic.chat.domain.pojo.config.DefaultMetricInfo;
import com.tencent.supersonic.chat.domain.pojo.config.EntityInternalDetail; import com.tencent.supersonic.chat.domain.pojo.config.EntityInternalDetail;
@@ -47,17 +47,17 @@ public class MockBeansConfiguration {
public static void buildHttpSemanticServiceImpl(SemanticLayer httpSemanticLayer, List<DimSchemaResp> dimensionDescs, public static void buildHttpSemanticServiceImpl(SemanticLayer httpSemanticLayer, List<DimSchemaResp> dimensionDescs,
List<MetricSchemaResp> metricDescs) { List<MetricSchemaResp> metricDescs) {
ChatConfigRichInfo chaConfigRichDesc = new ChatConfigRichInfo(); ChatConfigRichResp chaConfigRichDesc = new ChatConfigRichResp();
DefaultMetric defaultMetricDesc = new DefaultMetric(); DefaultMetric defaultMetricDesc = new DefaultMetric();
defaultMetricDesc.setUnit(3); defaultMetricDesc.setUnit(3);
defaultMetricDesc.setPeriod(Constants.DAY); defaultMetricDesc.setPeriod(Constants.DAY);
chaConfigRichDesc.setDefaultMetrics(new ArrayList<>(Arrays.asList(defaultMetricDesc))); // chaConfigRichDesc.setDefaultMetrics(new ArrayList<>(Arrays.asList(defaultMetricDesc)));
EntityRichInfo entityDesc = new EntityRichInfo(); EntityRichInfo entityDesc = new EntityRichInfo();
List<DimSchemaResp> dimensionDescs1 = new ArrayList<>(); List<DimSchemaResp> dimensionDescs1 = new ArrayList<>();
DimSchemaResp dimensionDesc = new DimSchemaResp(); DimSchemaResp dimensionDesc = new DimSchemaResp();
dimensionDesc.setId(162L); dimensionDesc.setId(162L);
dimensionDescs1.add(dimensionDesc); dimensionDescs1.add(dimensionDesc);
entityDesc.setEntityIds(dimensionDescs1); // entityDesc.setEntityIds(dimensionDescs1);
DimSchemaResp dimensionDesc2 = new DimSchemaResp(); DimSchemaResp dimensionDesc2 = new DimSchemaResp();
dimensionDesc2.setId(163L); dimensionDesc2.setId(163L);
@@ -71,14 +71,14 @@ public class MockBeansConfiguration {
metricDesc.setBizName("js_play_cnt"); metricDesc.setBizName("js_play_cnt");
metricDesc.setName("结算播放量"); metricDesc.setName("结算播放量");
entityInternalDetailDesc.setMetricList(new ArrayList<>(Arrays.asList(metricDesc))); entityInternalDetailDesc.setMetricList(new ArrayList<>(Arrays.asList(metricDesc)));
entityDesc.setEntityInternalDetailDesc(entityInternalDetailDesc); // entityDesc.setEntityInternalDetailDesc(entityInternalDetailDesc);
chaConfigRichDesc.setEntity(entityDesc); // chaConfigRichDesc.setEntity(entityDesc);
// when(httpSemanticLayer.getChatConfigRichInfo(anyLong())).thenReturn(chaConfigRichDesc); // when(httpSemanticLayer.getChatConfigRichInfo(anyLong())).thenReturn(chaConfigRichDesc);
DomainSchemaResp domainSchemaDesc = new DomainSchemaResp(); DomainSchemaResp domainSchemaDesc = new DomainSchemaResp();
domainSchemaDesc.setDimensions(dimensionDescs); domainSchemaDesc.setDimensions(dimensionDescs);
domainSchemaDesc.setMetrics(metricDescs); domainSchemaDesc.setMetrics(metricDescs);
when(httpSemanticLayer.getDomainSchemaInfo(anyLong())).thenReturn(domainSchemaDesc); // when(httpSemanticLayer.getDomainSchemaInfo(anyLong())).thenReturn(domainSchemaDesc);
DomainInfos domainInfos = new DomainInfos(); DomainInfos domainInfos = new DomainInfos();
when(SchemaInfoConverter.convert(httpSemanticLayer.getDomainSchemaInfo(anyList()))).thenReturn(domainInfos); when(SchemaInfoConverter.convert(httpSemanticLayer.getDomainSchemaInfo(anyList()))).thenReturn(domainInfos);
@@ -92,8 +92,8 @@ public class MockBeansConfiguration {
List<DefaultMetricInfo> defaultMetricInfos = new ArrayList<>(); List<DefaultMetricInfo> defaultMetricInfos = new ArrayList<>();
defaultMetricInfos.add(defaultMetricInfo); defaultMetricInfos.add(defaultMetricInfo);
ChatConfigInfo chaConfigDesc = new ChatConfigInfo(); ChatConfigResp chaConfigDesc = new ChatConfigResp();
chaConfigDesc.setDefaultMetrics(defaultMetricInfos); // chaConfigDesc.setDefaultMetrics(defaultMetricInfos);
when(configService.fetchConfigByDomainId(anyLong())).thenReturn(chaConfigDesc); when(configService.fetchConfigByDomainId(anyLong())).thenReturn(chaConfigDesc);
} }

View File

@@ -14,8 +14,12 @@ import com.hankcs.hanlp.seg.common.Term;
import com.hankcs.hanlp.seg.common.Vertex; import com.hankcs.hanlp.seg.common.Vertex;
import com.hankcs.hanlp.seg.common.WordNet; import com.hankcs.hanlp.seg.common.WordNet;
import com.hankcs.hanlp.utility.TextUtility; import com.hankcs.hanlp.utility.TextUtility;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.*;
public abstract class WordBasedSegment extends Segment { public abstract class WordBasedSegment extends Segment {

View File

@@ -6,12 +6,15 @@ import com.hankcs.hanlp.HanLP;
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.nlp.MapResult; import com.tencent.supersonic.common.nlp.MapResult;
import com.tencent.supersonic.common.nlp.NatureType;
import com.tencent.supersonic.common.nlp.WordNature; import com.tencent.supersonic.common.nlp.WordNature;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -173,5 +176,10 @@ public class HanlpHelper {
} }
} }
public static List<Term> getTerms(String text) {
return getSegment().seg(text.toLowerCase()).stream()
.filter(term -> term.getNature().startsWith(NatureType.NATURE_SPILT))
.collect(Collectors.toList());
}
} }

View File

@@ -0,0 +1,28 @@
package com.tencent.supersonic.common.enums;
public enum ConfigMode {
DETAIL("DETAIL"),
AGG("AGG"),
UNKNOWN("UNKNOWN");
private String mode;
ConfigMode(String mode) {
this.mode = mode;
}
public String getMode() {
return mode;
}
public static ConfigMode of(String agg) {
for (ConfigMode configMode : ConfigMode.values()) {
if (configMode.getMode().equalsIgnoreCase(agg)) {
return configMode;
}
}
return ConfigMode.UNKNOWN;
}
}

View File

@@ -15,7 +15,7 @@ public class DateConf {
private static final long serialVersionUID = 3074129990945004340L; private static final long serialVersionUID = 3074129990945004340L;
private DateMode dateMode; private DateMode dateMode = DateMode.RECENT_UNITS;
/** /**
* like 2021-10-22, dateMode=1 * like 2021-10-22, dateMode=1

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.common.util.calcite;
import org.apache.calcite.sql.dialect.MysqlSqlDialect;
public class S2MysqlSqlDialect extends MysqlSqlDialect {
public S2MysqlSqlDialect(Context context) {
super(context);
}
@Override
public void quoteStringLiteral(StringBuilder buf, String charsetName, String val) {
buf.append(this.literalQuoteString);
buf.append(val.replace(this.literalEndQuoteString, this.literalEscapedQuote));
buf.append(this.literalEndQuoteString);
}
}

View File

@@ -1,16 +1,24 @@
package com.tencent.supersonic.common.util.calcite; package com.tencent.supersonic.common.util.calcite;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.calcite.sql.SqlBasicCall; import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlDialect;
import org.apache.calcite.sql.SqlIdentifier; import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList; import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlOrderBy; import org.apache.calcite.sql.SqlOrderBy;
import org.apache.calcite.sql.SqlSelect; import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException; import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser; import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.util.SqlString;
import org.apache.commons.collections.CollectionUtils;
/** /**
* sql parse utils * sql parse utils
@@ -28,11 +36,14 @@ public class SqlParseUtils {
SqlParser parser = SqlParser.create(sql); SqlParser parser = SqlParser.create(sql);
SqlNode sqlNode = parser.parseQuery(); SqlNode sqlNode = parser.parseQuery();
SqlParserInfo sqlParserInfo = new SqlParserInfo(); SqlParserInfo sqlParserInfo = new SqlParserInfo();
handlerSQL(sqlNode, sqlParserInfo); handlerSQL(sqlNode, sqlParserInfo);
List<String> collect = sqlParserInfo.getAllFields().stream().distinct().collect(Collectors.toList()); sqlParserInfo.setAllFields(sqlParserInfo.getAllFields().stream().distinct().collect(Collectors.toList()));
sqlParserInfo.setSelectFields(
sqlParserInfo.getSelectFields().stream().distinct().collect(Collectors.toList()));
sqlParserInfo.setAllFields(collect);
return sqlParserInfo; return sqlParserInfo;
} catch (SqlParseException e) { } catch (SqlParseException e) {
throw new RuntimeException("getSqlParseInfo", e); throw new RuntimeException("getSqlParseInfo", e);
@@ -69,7 +80,8 @@ public class SqlParseUtils {
SqlNode query = sqlOrderBy.query; SqlNode query = sqlOrderBy.query;
handlerSQL(query, sqlParserInfo); handlerSQL(query, sqlParserInfo);
SqlNodeList orderList = sqlOrderBy.orderList; SqlNodeList orderList = sqlOrderBy.orderList;
handlerField(orderList, sqlParserInfo); Set<String> orderFields = handlerField(orderList);
sqlParserInfo.getAllFields().addAll(orderFields);
} }
/** /**
@@ -82,22 +94,26 @@ public class SqlParseUtils {
SqlSelect sqlSelect = (SqlSelect) select; SqlSelect sqlSelect = (SqlSelect) select;
SqlNodeList selectList = sqlSelect.getSelectList(); SqlNodeList selectList = sqlSelect.getSelectList();
List<String> allFields = sqlParserInfo.getAllFields();
selectList.getList().forEach(list -> { selectList.getList().forEach(list -> {
handlerField(list, sqlParserInfo); Set<String> selectFields = handlerField(list);
sqlParserInfo.getSelectFields().addAll(selectFields);
allFields.addAll(selectFields);
}); });
String tableName = handlerFrom(sqlSelect.getFrom()); String tableName = handlerFrom(sqlSelect.getFrom());
sqlParserInfo.setTableName(tableName); sqlParserInfo.setTableName(tableName);
if (sqlSelect.hasWhere()) { if (sqlSelect.hasWhere()) {
handlerField(sqlSelect.getWhere(), sqlParserInfo); allFields.addAll(handlerField(sqlSelect.getWhere()));
} }
if (sqlSelect.hasOrderBy()) { if (sqlSelect.hasOrderBy()) {
handlerField(sqlSelect.getOrderList(), sqlParserInfo); allFields.addAll(handlerField(sqlSelect.getOrderList()));
} }
SqlNodeList group = sqlSelect.getGroup(); SqlNodeList group = sqlSelect.getGroup();
if (group != null) { if (group != null) {
group.forEach(groupField -> { group.forEach(groupField -> {
handlerField(groupField, sqlParserInfo); allFields.addAll(handlerField(groupField));
}); });
} }
} }
@@ -115,7 +131,7 @@ public class SqlParseUtils {
SqlIdentifier sqlIdentifier = (SqlIdentifier) from; SqlIdentifier sqlIdentifier = (SqlIdentifier) from;
return sqlIdentifier.getSimple(); return sqlIdentifier.getSimple();
case AS: case AS:
SqlBasicCall sqlBasicCall = (SqlBasicCall) from; SqlBasicCall sqlBasicCall = (SqlBasicCall) from;
SqlNode sqlNode = sqlBasicCall.getOperandList().get(0); SqlNode sqlNode = sqlBasicCall.getOperandList().get(0);
SqlSelect sqlSelect = (SqlSelect) sqlNode; SqlSelect sqlSelect = (SqlSelect) sqlNode;
return handlerFrom(sqlSelect.getFrom()); return handlerFrom(sqlSelect.getFrom());
@@ -127,34 +143,120 @@ public class SqlParseUtils {
* handler field * handler field
* *
* @param field * @param field
* @param sqlParserInfo
*/ */
private static void handlerField(SqlNode field, SqlParserInfo sqlParserInfo) { private static Set<String> handlerField(SqlNode field) {
Set<String> fields = new HashSet<>();
SqlKind kind = field.getKind(); SqlKind kind = field.getKind();
switch (kind) { switch (kind) {
case AS: case AS:
List<SqlNode> operandList1 = ((SqlBasicCall) field).getOperandList(); List<SqlNode> operandList1 = ((SqlBasicCall) field).getOperandList();
SqlNode left_as = operandList1.get(0); SqlNode leftAs = operandList1.get(0);
handlerField(left_as, sqlParserInfo); fields.addAll(handlerField(leftAs));
break; break;
case IDENTIFIER: case IDENTIFIER:
SqlIdentifier sqlIdentifier = (SqlIdentifier) field; SqlIdentifier sqlIdentifier = (SqlIdentifier) field;
sqlParserInfo.getAllFields().add(sqlIdentifier.getSimple()); fields.add(sqlIdentifier.getSimple());
break; break;
default: default:
if (field instanceof SqlBasicCall) { if (field instanceof SqlBasicCall) {
List<SqlNode> operandList2 = ((SqlBasicCall) field).getOperandList(); List<SqlNode> operandList2 = ((SqlBasicCall) field).getOperandList();
for (int i = 0; i < operandList2.size(); i++) { for (int i = 0; i < operandList2.size(); i++) {
handlerField(operandList2.get(i), sqlParserInfo); fields.addAll(handlerField(operandList2.get(i)));
} }
} }
if (field instanceof SqlNodeList) { if (field instanceof SqlNodeList) {
((SqlNodeList) field).getList().forEach(node -> { ((SqlNodeList) field).getList().forEach(node -> {
handlerField(node, sqlParserInfo); fields.addAll(handlerField(node));
}); });
} }
break; break;
} }
return fields;
} }
public static String addAliasToSql(String sql) throws SqlParseException {
SqlParser parser = SqlParser.create(sql);
SqlNode sqlNode = parser.parseStmt();
if (!(sqlNode instanceof SqlSelect)) {
return sql;
}
SqlNodeList selectList = ((SqlSelect) sqlNode).getSelectList();
for (SqlNode node : selectList) {
if (node instanceof SqlBasicCall) {
SqlBasicCall sqlBasicCall = (SqlBasicCall) node;
List<SqlNode> operandList = sqlBasicCall.getOperandList();
if (CollectionUtils.isNotEmpty(operandList) && operandList.size() == 1) {
SqlIdentifier sqlIdentifier = (SqlIdentifier) operandList.get(0);
String simple = sqlIdentifier.getSimple();
SqlBasicCall aliasedNode = new SqlBasicCall(
SqlStdOperatorTable.AS,
new SqlNode[]{sqlBasicCall, new SqlIdentifier(simple.toLowerCase(), SqlParserPos.ZERO)},
SqlParserPos.ZERO);
selectList.set(selectList.indexOf(node), aliasedNode);
}
}
}
SqlDialect dialect = new S2MysqlSqlDialect(S2MysqlSqlDialect.DEFAULT_CONTEXT);
SqlString newSql = sqlNode.toSqlString(dialect);
return newSql.getSql().replaceAll("`", "");
}
public static String addFieldsToSql(String sql, List<String> addFields) throws SqlParseException {
if (CollectionUtils.isEmpty(addFields)) {
return sql;
}
SqlParser parser = SqlParser.create(sql);
SqlNode sqlNode = parser.parseStmt();
SqlNodeList selectList = getSelectList(sqlNode);
// agg to field not allow to add field
if (Objects.isNull(selectList)) {
return sql;
}
for (SqlNode node : selectList) {
if (node instanceof SqlBasicCall) {
return sql;
}
}
Set<String> existFields = new HashSet<>();
for (SqlNode node : selectList.getList()) {
if (node instanceof SqlIdentifier) {
String fieldName = ((SqlIdentifier) node).getSimple();
existFields.add(fieldName.toLowerCase());
}
}
for (String addField : addFields) {
if (existFields.contains(addField.toLowerCase())) {
continue;
}
SqlIdentifier newField = new SqlIdentifier(addField, SqlParserPos.ZERO);
selectList.add(newField);
existFields.add(addField.toLowerCase());
}
SqlDialect dialect = new S2MysqlSqlDialect(S2MysqlSqlDialect.DEFAULT_CONTEXT);
SqlString newSql = sqlNode.toSqlString(dialect);
return newSql.getSql().replaceAll("`", "");
}
private static SqlNodeList getSelectList(SqlNode sqlNode) {
SqlKind kind = sqlNode.getKind();
switch (kind) {
case SELECT:
SqlSelect sqlSelect = (SqlSelect) sqlNode;
return sqlSelect.getSelectList();
case ORDER_BY:
SqlOrderBy sqlOrderBy = (SqlOrderBy) sqlNode;
SqlSelect query = (SqlSelect) sqlOrderBy.query;
return query.getSelectList();
}
return null;
}
} }

View File

@@ -12,6 +12,7 @@ public class SqlParserInfo implements Serializable {
private String tableName; private String tableName;
private List<String> allFields = new ArrayList<>(); private List<String> selectFields = new ArrayList<>();
private List<String> allFields = new ArrayList<>();
} }

View File

@@ -0,0 +1,106 @@
package com.tencent.supersonic.common.util.calcite;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.calcite.sql.parser.SqlParseException;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
/**
* SqlParseUtils Test
*
* @date 2023/7/12 12:00
*/
class SqlParseUtilsTest {
@Test
void addAliasToSql() throws SqlParseException {
String addAliasToSql = SqlParseUtils.addAliasToSql(
"select sum(pv) from ( select * from t_1 where sys_imp_date >= '2023-07-07' and sys_imp_date <= '2023-07-07' ) as t_sub_1");
Assert.assertTrue(addAliasToSql.toLowerCase().contains("as `pv`"));
}
@Test
void addFieldToSql() throws SqlParseException {
String addFieldToSql = SqlParseUtils.addFieldsToSql(
"select pv from ( select * from t_1 where sys_imp_date >= '2023-07-07' and sys_imp_date <= '2023-07-07' ) as t_sub_1",
Collections.singletonList("uv"));
Assert.assertTrue(addFieldToSql.toLowerCase().contains("uv"));
addFieldToSql = SqlParseUtils.addFieldsToSql(
"select uv from ( select * from t_1 where sys_imp_date >= '2023-07-07' and sys_imp_date <= '2023-07-07' ) as t_sub_1 order by play_count desc limit 10",
Collections.singletonList("pv"));
Assert.assertTrue(addFieldToSql.toLowerCase().contains("pv"));
addFieldToSql = SqlParseUtils.addFieldsToSql(
"select uv from ( select * from t_1 where sys_imp_date >= '2023-07-07' and sys_imp_date <= '2023-07-07' ) as t_sub_1 where user_id = '张三' order by play_count desc limit 10",
Collections.singletonList("pv"));
Assert.assertTrue(addFieldToSql.toLowerCase().contains("pv"));
}
@Test
void getSqlParseInfo() {
SqlParserInfo sqlParserInfo = SqlParseUtils.getSqlParseInfo(
"select pv from ( select * from t_1 where sys_imp_date >= '2023-07-07' and sys_imp_date <= '2023-07-07' ) as t_sub_1 ");
Assert.assertTrue(sqlParserInfo.getTableName().equalsIgnoreCase("t_1"));
List<String> collect = sqlParserInfo.getAllFields().stream().map(field -> field.toLowerCase())
.collect(Collectors.toList());
Assert.assertTrue(collect.contains("pv"));
Assert.assertTrue(!collect.contains("uv"));
List<String> selectFields = sqlParserInfo.getSelectFields().stream().map(field -> field.toLowerCase())
.collect(Collectors.toList());
Assert.assertTrue(selectFields.contains("pv"));
Assert.assertTrue(!selectFields.contains("uv"));
sqlParserInfo = SqlParseUtils.getSqlParseInfo(
"select uv from t_1 order by play_count desc limit 10");
Assert.assertTrue(sqlParserInfo.getTableName().equalsIgnoreCase("t_1"));
collect = sqlParserInfo.getAllFields().stream().map(field -> field.toLowerCase())
.collect(Collectors.toList());
Assert.assertTrue(collect.contains("uv"));
Assert.assertTrue(collect.contains("play_count"));
Assert.assertTrue(!collect.contains("pv"));
selectFields = sqlParserInfo.getSelectFields().stream().map(field -> field.toLowerCase())
.collect(Collectors.toList());
Assert.assertTrue(selectFields.contains("uv"));
Assert.assertTrue(!selectFields.contains("pv"));
Assert.assertTrue(!selectFields.contains("play_count"));
sqlParserInfo = SqlParseUtils.getSqlParseInfo(
"select uv from ( select * from t_1 where sys_imp_date >= '2023-07-07' and sys_imp_date <= '2023-07-07' ) as t_sub_1 where user_id = '1' order by play_count desc limit 10");
Assert.assertTrue(sqlParserInfo.getTableName().equalsIgnoreCase("t_1"));
collect = sqlParserInfo.getAllFields().stream().map(field -> field.toLowerCase())
.collect(Collectors.toList());
Assert.assertTrue(collect.contains("uv"));
Assert.assertTrue(collect.contains("play_count"));
Assert.assertTrue(collect.contains("user_id"));
Assert.assertTrue(!collect.contains("pv"));
selectFields = sqlParserInfo.getSelectFields().stream().map(field -> field.toLowerCase())
.collect(Collectors.toList());
Assert.assertTrue(selectFields.contains("uv"));
Assert.assertTrue(!selectFields.contains("pv"));
Assert.assertTrue(!selectFields.contains("user_id"));
Assert.assertTrue(!selectFields.contains("play_count"));
}
}

View File

@@ -5,7 +5,7 @@ baseDir=$(readlink -f $binDir/../)
confDir=$baseDir/conf confDir=$baseDir/conf
source ${baseDir}/bin/env.sh source ${baseDir}/bin/env.sh
commond=$1 command=$1
function start() function start()
{ {
@@ -33,7 +33,7 @@ function stop()
fi fi
} }
case "$commond" in case "$command" in
start) start)
echo -e "Starting $APP_NAME" echo -e "Starting $APP_NAME"
start start

View File

@@ -6,8 +6,8 @@ com.tencent.supersonic.chat.api.component.SchemaMapper=\
com.tencent.supersonic.chat.api.component.SemanticParser=\ com.tencent.supersonic.chat.api.component.SemanticParser=\
com.tencent.supersonic.chat.application.parser.DomainSemanticParser, \ com.tencent.supersonic.chat.application.parser.DomainSemanticParser, \
com.tencent.supersonic.chat.application.parser.TimeSemanticParser, \ com.tencent.supersonic.chat.application.parser.TimeSemanticParser, \
com.tencent.supersonic.chat.application.parser.AggregateSemanticParser com.tencent.supersonic.chat.application.parser.AggregateSemanticParser, \
# com.tencent.supersonic.chat.application.parser.LLMSemanticParser com.tencent.supersonic.chat.application.parser.LLMSemanticParser
com.tencent.supersonic.chat.api.component.SemanticLayer=\ com.tencent.supersonic.chat.api.component.SemanticLayer=\

View File

@@ -4,4 +4,16 @@ lucy _1_2 31
dean _1_2 36 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
陈奕迅 _2_7 100
林俊杰 _2_7 100
张碧晨 _2_7 100
程响 _2_7 100
Taylor#Swift _2_7 100
中国 _2_4 100
欧美 _2_4 100
流行 _2_6 100
爱情 _2_6 100
激情 _2_6 100
国风 _2_6 100

View File

@@ -3,7 +3,15 @@ insert into s2_user (id, `name`, password, display_name, email) values (2, 'jack
insert into s2_user (id, `name`, password, display_name, email) values (3, 'tom','123456','tom','tom@xx.com'); insert into s2_user (id, `name`, password, display_name, email) values (3, 'tom','123456','tom','tom@xx.com');
insert into s2_user (id, `name`, password, display_name, email) values (4, 'lucy','123456','lucy','lucy@xx.com'); insert into s2_user (id, `name`, password, display_name, email) values (4, 'lucy','123456','lucy','lucy@xx.com');
insert into s2_chat_config (`id` ,`domain_id` ,`default_metrics`,`visibility`,`entity_info` ,`dictionary_info`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` ) values (1,1,'[{"metricId":1,"unit":7,"period":"DAY"}]','{"blackDimIdList":[],"blackMetricIdList":[]}','{"entityIds":[2],"names":["用户","用户姓名"],"detailData":{"dimensionIds":[1,2],"metricIds":[2]}}','[{"itemId":1,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":2,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":3,"type":"DIMENSION","blackList":[],"isDictInfo":true}]','2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1); -- insert into s2_chat_config (`id` ,`domain_id` ,`default_metrics`,`visibility`,`entity_info` ,`dictionary_info`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` ) values (1,1,'[{"metricId":1,"unit":7,"period":"DAY"}]','{"blackDimIdList":[],"blackMetricIdList":[]}','{"entityIds":[2],"names":["用户","用户姓名"],"detailData":{"dimensionIds":[1,2],"metricIds":[2]}}','[{"itemId":1,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":2,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":3,"type":"DIMENSION","blackList":[],"isDictInfo":true}]','2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1);
insert into s2_chat_config (`id` ,`domain_id` ,`chat_detail_config`,`chat_agg_config`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` )
values (1,1,'{"visibility":{"blackDimIdList":[1],"blackMetricIdList":[2]},"knowledgeInfos":[{"itemId":2,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[1,2],"metricIds":[1],"unit":1,"period":"DAY"},"entity":null}',
'{"visibility":{"blackDimIdList":[3],"blackMetricIdList":[3]},"knowledgeInfos":[{"itemId":2,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[1,2],"metricIds":[1],"unit":1,"period":"DAY"}}',
'2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1);
insert into s2_chat_config (`id` ,`domain_id` ,`chat_detail_config`,`chat_agg_config`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` )
values (2,2,'{"visibility":{"blackDimIdList":[],"blackMetricIdList":[]},"knowledgeInfos":[{"itemId":7,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[4,5,6,7],"metricIds":[4],"unit":7,"period":"DAY"},"entity":{"entityId":1,"names":["歌手","艺人"]}}',
'{"visibility":{"blackDimIdList":[],"blackMetricIdList":[]},"knowledgeInfos":[{"itemId":7,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[4,5,6,7],"metricIds":[4],"unit":7,"period":"DAY"}}',
'2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1);
insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (1, '超音数访问统计','2023-06-10 10:00:52.495','2023-06-10 10:00:52','admin','您好欢迎使用内容智能小Q','0','0'); insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (1, '超音数访问统计','2023-06-10 10:00:52.495','2023-06-10 10:00:52','admin','您好欢迎使用内容智能小Q','0','0');
insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (2, '用户访问统计','2023-06-10 10:01:04.528','2023-06-10 10:01:04','admin','您好欢迎使用内容智能小Q','0','0'); insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (2, '用户访问统计','2023-06-10 10:01:04.528','2023-06-10 10:01:04','admin','您好欢迎使用内容智能小Q','0','0');
@@ -16,4 +24,4 @@ insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,
insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(3, '2023-06-10 10:40:49.877', '访问', 'admin',0,1,'{"queryMode":"METRIC_ORDERBY","querySql":"SELECT `sys_imp_date` , `page` , `uv` , `pv` FROM ( SELECT `sys_imp_date` , `page` , `s2_pv_uv_statis_uv` AS `uv` , `s2_pv_uv_statis_pv` AS `pv` FROM ( SELECT COUNT ( DISTINCT `s2_pv_uv_statis_uv` ) AS `s2_pv_uv_statis_uv` , SUM ( `s2_pv_uv_statis_pv` ) AS `s2_pv_uv_statis_pv` , `sys_imp_date` , `page` FROM ( SELECT `uv` AS `s2_pv_uv_statis_uv` , `pv` AS `s2_pv_uv_statis_pv` , `imp_date` AS `sys_imp_date` , `page` AS `page` FROM ( SELECT `imp_date` , `user_name` , `page` , 1 AS `pv` , `user_name` AS `uv` FROM `s2_pv_uv_statis` ) AS `s2_pv_uv_statis` ) AS `src00_s2_pv_uv_statis_022c` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' ) GROUP BY `sys_imp_date` , `page` ) AS `s2_pv_uv_statis_0` ) AS `s2_pv_uv_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"页面","type":"VARCHAR","nameEn":"page","showType":"CATEGORY","authorized":true},{"name":"访问人数","type":"BIGINT","nameEn":"uv","showType":"NUMBER","authorized":true},{"name":"访问次数","type":"BIGINT","nameEn":"pv","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"}},"chatContext":{"queryMode":"METRIC_ORDERBY","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":3,"name":"访问人数","bizName":"uv","status":1,"sensitiveLevel":0},{"id":2,"name":"访问次数","bizName":"pv","status":1,"sensitiveLevel":0}],"dimensions":[{"id":3,"name":"页面","bizName":"page","status":1,"sensitiveLevel":0},{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","page":"p1","uv":2,"pv":2},{"sys_imp_date":"2023-06-03","page":"p2","uv":3,"pv":3},{"sys_imp_date":"2023-06-03","page":"p3","uv":2,"pv":2},{"sys_imp_date":"2023-06-03","page":"p4","uv":1,"pv":1},{"sys_imp_date":"2023-06-03","page":"p5","uv":3,"pv":3},{"sys_imp_date":"2023-06-04","page":"p1","uv":2,"pv":3},{"sys_imp_date":"2023-06-04","page":"p2","uv":1,"pv":1},{"sys_imp_date":"2023-06-04","page":"p3","uv":2,"pv":2},{"sys_imp_date":"2023-06-04","page":"p4","uv":3,"pv":4},{"sys_imp_date":"2023-06-04","page":"p5","uv":3,"pv":4}]}',0,''); insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(3, '2023-06-10 10:40:49.877', '访问', 'admin',0,1,'{"queryMode":"METRIC_ORDERBY","querySql":"SELECT `sys_imp_date` , `page` , `uv` , `pv` FROM ( SELECT `sys_imp_date` , `page` , `s2_pv_uv_statis_uv` AS `uv` , `s2_pv_uv_statis_pv` AS `pv` FROM ( SELECT COUNT ( DISTINCT `s2_pv_uv_statis_uv` ) AS `s2_pv_uv_statis_uv` , SUM ( `s2_pv_uv_statis_pv` ) AS `s2_pv_uv_statis_pv` , `sys_imp_date` , `page` FROM ( SELECT `uv` AS `s2_pv_uv_statis_uv` , `pv` AS `s2_pv_uv_statis_pv` , `imp_date` AS `sys_imp_date` , `page` AS `page` FROM ( SELECT `imp_date` , `user_name` , `page` , 1 AS `pv` , `user_name` AS `uv` FROM `s2_pv_uv_statis` ) AS `s2_pv_uv_statis` ) AS `src00_s2_pv_uv_statis_022c` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' ) GROUP BY `sys_imp_date` , `page` ) AS `s2_pv_uv_statis_0` ) AS `s2_pv_uv_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"页面","type":"VARCHAR","nameEn":"page","showType":"CATEGORY","authorized":true},{"name":"访问人数","type":"BIGINT","nameEn":"uv","showType":"NUMBER","authorized":true},{"name":"访问次数","type":"BIGINT","nameEn":"pv","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"}},"chatContext":{"queryMode":"METRIC_ORDERBY","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":3,"name":"访问人数","bizName":"uv","status":1,"sensitiveLevel":0},{"id":2,"name":"访问次数","bizName":"pv","status":1,"sensitiveLevel":0}],"dimensions":[{"id":3,"name":"页面","bizName":"page","status":1,"sensitiveLevel":0},{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","page":"p1","uv":2,"pv":2},{"sys_imp_date":"2023-06-03","page":"p2","uv":3,"pv":3},{"sys_imp_date":"2023-06-03","page":"p3","uv":2,"pv":2},{"sys_imp_date":"2023-06-03","page":"p4","uv":1,"pv":1},{"sys_imp_date":"2023-06-03","page":"p5","uv":3,"pv":3},{"sys_imp_date":"2023-06-04","page":"p1","uv":2,"pv":3},{"sys_imp_date":"2023-06-04","page":"p2","uv":1,"pv":1},{"sys_imp_date":"2023-06-04","page":"p3","uv":2,"pv":2},{"sys_imp_date":"2023-06-04","page":"p4","uv":3,"pv":4},{"sys_imp_date":"2023-06-04","page":"p5","uv":3,"pv":4}]}',0,'');
insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(4, '2023-06-10 10:41:18.589','alice 访问次数','admin',0,2,'{"queryMode":"METRIC_FILTER","querySql":"SELECT `sys_imp_date` , `pv` FROM ( SELECT `sys_imp_date` , `s2_pv_uv_statis_pv` AS `pv` FROM ( SELECT SUM ( `s2_pv_uv_statis_pv` ) AS `s2_pv_uv_statis_pv` , `sys_imp_date` FROM ( SELECT `user_name` , `pv` AS `s2_pv_uv_statis_pv` , `imp_date` AS `sys_imp_date` FROM ( SELECT `imp_date` , `user_name` , `page` , 1 AS `pv` , `user_name` AS `uv` FROM `s2_pv_uv_statis` ) AS `s2_pv_uv_statis` ) AS `src00_s2_pv_uv_statis_b825` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' AND `user_name` = ''alice'' ) GROUP BY `sys_imp_date` ) AS `s2_pv_uv_statis_0` ) AS `s2_pv_uv_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"访问次数","type":"BIGINT","nameEn":"pv","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"},"dimensions":[{"itemId":1,"name":"部门","bizName":"department","value":"sales"},{"itemId":2,"name":"用户名","bizName":"user_name","value":"alice"}],"metrics":[{"itemId":2,"name":"访问次数","bizName":"pv","value":"2"}],"entityId":"alice"},"chatContext":{"queryMode":"METRIC_FILTER","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":2,"name":"访问次数","bizName":"pv","status":1,"sensitiveLevel":0}],"dimensions":[{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[{"bizName":"user_name","name":"用户名","operator":"=","value":"alice","elementID":2}],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","pv":2},{"sys_imp_date":"2023-06-04","pv":2},{"sys_imp_date":"2023-06-06","pv":2},{"sys_imp_date":"2023-06-07","pv":2},{"sys_imp_date":"2023-06-08","pv":5},{"sys_imp_date":"2023-06-09","pv":2}]}',0,''); insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(4, '2023-06-10 10:41:18.589','alice 访问次数','admin',0,2,'{"queryMode":"METRIC_FILTER","querySql":"SELECT `sys_imp_date` , `pv` FROM ( SELECT `sys_imp_date` , `s2_pv_uv_statis_pv` AS `pv` FROM ( SELECT SUM ( `s2_pv_uv_statis_pv` ) AS `s2_pv_uv_statis_pv` , `sys_imp_date` FROM ( SELECT `user_name` , `pv` AS `s2_pv_uv_statis_pv` , `imp_date` AS `sys_imp_date` FROM ( SELECT `imp_date` , `user_name` , `page` , 1 AS `pv` , `user_name` AS `uv` FROM `s2_pv_uv_statis` ) AS `s2_pv_uv_statis` ) AS `src00_s2_pv_uv_statis_b825` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' AND `user_name` = ''alice'' ) GROUP BY `sys_imp_date` ) AS `s2_pv_uv_statis_0` ) AS `s2_pv_uv_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"访问次数","type":"BIGINT","nameEn":"pv","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"},"dimensions":[{"itemId":1,"name":"部门","bizName":"department","value":"sales"},{"itemId":2,"name":"用户名","bizName":"user_name","value":"alice"}],"metrics":[{"itemId":2,"name":"访问次数","bizName":"pv","value":"2"}],"entityId":"alice"},"chatContext":{"queryMode":"METRIC_FILTER","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":2,"name":"访问次数","bizName":"pv","status":1,"sensitiveLevel":0}],"dimensions":[{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[{"bizName":"user_name","name":"用户名","operator":"=","value":"alice","elementID":2}],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","pv":2},{"sys_imp_date":"2023-06-04","pv":2},{"sys_imp_date":"2023-06-06","pv":2},{"sys_imp_date":"2023-06-07","pv":2},{"sys_imp_date":"2023-06-08","pv":5},{"sys_imp_date":"2023-06-09","pv":2}]}',0,'');
insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(5, '2023-06-10 10:41:48.211','停留时长','admin',0,2,'{"queryMode":"METRIC_FILTER","querySql":"SELECT `sys_imp_date` , `stay_hours` FROM ( SELECT `sys_imp_date` , `s2_stay_time_statis_stay_hours` AS `stay_hours` FROM ( SELECT SUM ( `s2_stay_time_statis_stay_hours` ) AS `s2_stay_time_statis_stay_hours` , `sys_imp_date` FROM ( SELECT `user_name` , `stay_hours` AS `s2_stay_time_statis_stay_hours` , `imp_date` AS `sys_imp_date` FROM ( SELECT `imp_date` , `page` , `user_name` , `stay_hours` FROM `s2_stay_time_statis` ) AS `s2_stay_time_statis` ) AS `src00_s2_stay_time_statis_df18` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' AND `user_name` = ''alice'' ) GROUP BY `sys_imp_date` ) AS `s2_stay_time_statis_0` ) AS `s2_stay_time_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"停留时长","type":"DOUBLE","nameEn":"stay_hours","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"},"dimensions":[{"itemId":1,"name":"部门","bizName":"department","value":"sales"},{"itemId":2,"name":"用户名","bizName":"user_name","value":"alice"}],"metrics":[{"itemId":2,"name":"访问次数","bizName":"pv","value":"2"}],"entityId":"alice"},"chatContext":{"queryMode":"METRIC_FILTER","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":1,"name":"停留时长","bizName":"stay_hours","status":1,"sensitiveLevel":0}],"dimensions":[{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[{"bizName":"user_name","name":"用户名","operator":"=","value":"alice","elementID":2}],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","stay_hours":0.5963801306980994},{"sys_imp_date":"2023-06-04","stay_hours":1.5120376931855422},{"sys_imp_date":"2023-06-06","stay_hours":3.7790223355266317},{"sys_imp_date":"2023-06-07","stay_hours":0.8654528466186735},{"sys_imp_date":"2023-06-08","stay_hours":0.9796159603778489},{"sys_imp_date":"2023-06-09","stay_hours":0.6705580511822682}]}',0,''); insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(5, '2023-06-10 10:41:48.211','停留时长','admin',0,2,'{"queryMode":"METRIC_FILTER","querySql":"SELECT `sys_imp_date` , `stay_hours` FROM ( SELECT `sys_imp_date` , `s2_stay_time_statis_stay_hours` AS `stay_hours` FROM ( SELECT SUM ( `s2_stay_time_statis_stay_hours` ) AS `s2_stay_time_statis_stay_hours` , `sys_imp_date` FROM ( SELECT `user_name` , `stay_hours` AS `s2_stay_time_statis_stay_hours` , `imp_date` AS `sys_imp_date` FROM ( SELECT `imp_date` , `page` , `user_name` , `stay_hours` FROM `s2_stay_time_statis` ) AS `s2_stay_time_statis` ) AS `src00_s2_stay_time_statis_df18` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' AND `user_name` = ''alice'' ) GROUP BY `sys_imp_date` ) AS `s2_stay_time_statis_0` ) AS `s2_stay_time_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"停留时长","type":"DOUBLE","nameEn":"stay_hours","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"},"dimensions":[{"itemId":1,"name":"部门","bizName":"department","value":"sales"},{"itemId":2,"name":"用户名","bizName":"user_name","value":"alice"}],"metrics":[{"itemId":2,"name":"访问次数","bizName":"pv","value":"2"}],"entityId":"alice"},"chatContext":{"queryMode":"METRIC_FILTER","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":1,"name":"停留时长","bizName":"stay_hours","status":1,"sensitiveLevel":0}],"dimensions":[{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[{"bizName":"user_name","name":"用户名","operator":"=","value":"alice","elementID":2}],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","stay_hours":0.5963801306980994},{"sys_imp_date":"2023-06-04","stay_hours":1.5120376931855422},{"sys_imp_date":"2023-06-06","stay_hours":3.7790223355266317},{"sys_imp_date":"2023-06-07","stay_hours":0.8654528466186735},{"sys_imp_date":"2023-06-08","stay_hours":0.9796159603778489},{"sys_imp_date":"2023-06-09","stay_hours":0.6705580511822682}]}',0,'');
insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(6, '2023-06-10 10:42:02.184','访问','admin',0,2,'{"queryMode":"METRIC_FILTER","querySql":"SELECT `sys_imp_date` , `stay_hours` FROM ( SELECT `sys_imp_date` , `s2_stay_time_statis_stay_hours` AS `stay_hours` FROM ( SELECT SUM ( `s2_stay_time_statis_stay_hours` ) AS `s2_stay_time_statis_stay_hours` , `sys_imp_date` FROM ( SELECT `user_name` , `stay_hours` AS `s2_stay_time_statis_stay_hours` , `imp_date` AS `sys_imp_date` FROM ( SELECT `imp_date` , `page` , `user_name` , `stay_hours` FROM `s2_stay_time_statis` ) AS `s2_stay_time_statis` ) AS `src00_s2_stay_time_statis_df18` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' AND `user_name` = ''alice'' ) GROUP BY `sys_imp_date` ) AS `s2_stay_time_statis_0` ) AS `s2_stay_time_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"停留时长","type":"DOUBLE","nameEn":"stay_hours","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"},"dimensions":[{"itemId":1,"name":"部门","bizName":"department","value":"sales"},{"itemId":2,"name":"用户名","bizName":"user_name","value":"alice"}],"metrics":[{"itemId":2,"name":"访问次数","bizName":"pv","value":"2"}],"entityId":"alice"},"chatContext":{"queryMode":"METRIC_FILTER","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":1,"name":"停留时长","bizName":"stay_hours","status":1,"sensitiveLevel":0}],"dimensions":[{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[{"bizName":"user_name","name":"用户名","operator":"=","value":"alice","elementID":2}],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","stay_hours":0.5963801306980994},{"sys_imp_date":"2023-06-04","stay_hours":1.5120376931855422},{"sys_imp_date":"2023-06-06","stay_hours":3.7790223355266317},{"sys_imp_date":"2023-06-07","stay_hours":0.8654528466186735},{"sys_imp_date":"2023-06-08","stay_hours":0.9796159603778489},{"sys_imp_date":"2023-06-09","stay_hours":0.6705580511822682}]}',0,''); insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,`query_state`,`chat_id`,`query_response`,`score`,`feedback`) VALUES(6, '2023-06-10 10:42:02.184','访问','admin',0,2,'{"queryMode":"METRIC_FILTER","querySql":"SELECT `sys_imp_date` , `stay_hours` FROM ( SELECT `sys_imp_date` , `s2_stay_time_statis_stay_hours` AS `stay_hours` FROM ( SELECT SUM ( `s2_stay_time_statis_stay_hours` ) AS `s2_stay_time_statis_stay_hours` , `sys_imp_date` FROM ( SELECT `user_name` , `stay_hours` AS `s2_stay_time_statis_stay_hours` , `imp_date` AS `sys_imp_date` FROM ( SELECT `imp_date` , `page` , `user_name` , `stay_hours` FROM `s2_stay_time_statis` ) AS `s2_stay_time_statis` ) AS `src00_s2_stay_time_statis_df18` WHERE ( `sys_imp_date` >= ''2023-06-03'' AND `sys_imp_date` <= ''2023-06-09'' AND `user_name` = ''alice'' ) GROUP BY `sys_imp_date` ) AS `s2_stay_time_statis_0` ) AS `s2_stay_time_statis_1` LIMIT 10","queryState":0,"queryColumns":[{"name":"date","type":"VARCHAR","nameEn":"sys_imp_date","showType":"DATE","authorized":true},{"name":"停留时长","type":"DOUBLE","nameEn":"stay_hours","showType":"NUMBER","authorized":true}],"entityInfo":{"domainInfo":{"itemId":1,"name":"超音数","bizName":"supersonic","words":["用户","用户姓名"],"primaryEntityBizName":"user_name"},"dimensions":[{"itemId":1,"name":"部门","bizName":"department","value":"sales"},{"itemId":2,"name":"用户名","bizName":"user_name","value":"alice"}],"metrics":[{"itemId":2,"name":"访问次数","bizName":"pv","value":"2"}],"entityId":"alice"},"chatContext":{"queryMode":"METRIC_FILTER","domainId":1,"domainName":"超音数","entity":0,"metrics":[{"id":1,"name":"停留时长","bizName":"stay_hours","status":1,"sensitiveLevel":0}],"dimensions":[{"bizName":"sys_imp_date","status":1,"sensitiveLevel":0}],"dimensionFilters":[{"bizName":"user_name","name":"用户名","operator":"=","value":"alice","elementID":2}],"metricFilters":[],"orders":[],"dateInfo":{"dateMode":"RECENT_UNITS","startDate":"2023-06-03","endDate":"2023-06-09","dateList":[],"unit":7,"period":"DAY"},"limit":10,"nativeQuery":false},"queryResults":[{"sys_imp_date":"2023-06-03","stay_hours":0.5963801306980994},{"sys_imp_date":"2023-06-04","stay_hours":1.5120376931855422},{"sys_imp_date":"2023-06-06","stay_hours":3.7790223355266317},{"sys_imp_date":"2023-06-07","stay_hours":0.8654528466186735},{"sys_imp_date":"2023-06-08","stay_hours":0.9796159603778489},{"sys_imp_date":"2023-06-09","stay_hours":0.6705580511822682}]}',0,'');

View File

@@ -37,15 +37,11 @@ CREATE TABLE `s2_chat_query`
PRIMARY KEY (`question_id`) PRIMARY KEY (`question_id`)
); );
CREATE TABLE IF NOT EXISTS `s2_chat_config` ( CREATE TABLE IF NOT EXISTS `s2_chat_config` (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT DEFAULT NULL , `domain_id` INT DEFAULT NULL ,
`default_metrics` varchar(655) DEFAULT NULL, `chat_detail_config` varchar(655) ,
`visibility` varchar(655) , -- invisible dimension metric information `chat_agg_config` varchar(655) ,
`entity_info` varchar(655) ,
`dictionary_info` varchar(655) , -- dictionary-related dimension setting information
`created_at` TIMESTAMP NOT NULL , `created_at` TIMESTAMP NOT NULL ,
`updated_at` TIMESTAMP NOT NULL , `updated_at` TIMESTAMP NOT NULL ,
`created_by` varchar(100) NOT NULL , `created_by` varchar(100) NOT NULL ,
@@ -53,6 +49,22 @@ CREATE TABLE IF NOT EXISTS `s2_chat_config` (
`status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted `status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ; ) ;
-- CREATE TABLE IF NOT EXISTS `s2_chat_config` (
-- `id` INT NOT NULL AUTO_INCREMENT,
-- `domain_id` INT DEFAULT NULL ,
-- `default_metrics` varchar(655) DEFAULT NULL,
-- `visibility` varchar(655) , -- invisible dimension metric information
-- `entity_info` varchar(655) ,
-- `dictionary_info` varchar(655) , -- dictionary-related dimension setting information
-- `created_at` TIMESTAMP NOT NULL ,
-- `updated_at` TIMESTAMP NOT NULL ,
-- `created_by` varchar(100) NOT NULL ,
-- `updated_by` varchar(100) NOT NULL ,
-- `status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted
-- PRIMARY KEY (`id`)
-- ) ;
COMMENT ON TABLE s2_chat_config IS 'chat config information table '; COMMENT ON TABLE s2_chat_config IS 'chat config information table ';

View File

@@ -90,7 +90,7 @@
</manifest> </manifest>
</archive> </archive>
<descriptors> <descriptors>
<descriptor>../../assembly/build/build.xml</descriptor> <descriptor>../semantic/src/main/build/build.xml</descriptor>
</descriptors> </descriptors>
</configuration> </configuration>
<executions> <executions>

View File

@@ -5,7 +5,7 @@ baseDir=$(readlink -f $binDir/../)
confDir=$baseDir/conf confDir=$baseDir/conf
source ${baseDir}/bin/env.sh source ${baseDir}/bin/env.sh
commond=$1 command=$1
function start() function start()
{ {
@@ -33,7 +33,7 @@ function stop()
fi fi
} }
case "$commond" in case "$command" in
start) start)
echo -e "Starting $APP_NAME" echo -e "Starting $APP_NAME"
start start

View File

@@ -0,0 +1,39 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>bin</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0777</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0777</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -20,4 +20,4 @@ spring:
authentication: authentication:
enable: false enable: false
exclude: exclude:
path: /api/auth/user/register,/api/auth/user/login path: /api/auth/user/register,/api/auth/user/login

View File

@@ -1,17 +1,27 @@
insert into s2_database (id, domain_id , `name`, description, `type` ,config ,created_at ,created_by ,updated_at ,updated_by) VALUES(1, 1, 'H2数据实例', '', 'h2', '{"password":"semantic","url":"jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false","userName":"root"}', '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin'); insert into s2_database (id, domain_id , `name`, description, `type` ,config ,created_at ,created_by ,updated_at ,updated_by) VALUES(1, 1, 'H2数据实例', '', 'h2', '{"password":"semantic","url":"jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false","userName":"root"}', '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin');
insert into s2_database (id, domain_id , `name`, description, `type` ,config ,created_at ,created_by ,updated_at ,updated_by) VALUES(2, 2, 'H2数据实例', '', 'h2', '{"password":"semantic","url":"jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false","userName":"root"}', '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, '停留时长统计', 's2_stay_time_statis', '停留时长统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_stay_time_statis_stay_hours","expr":"stay_hours","isCreateMetric":1,"name":"停留时长"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, page,user_name,stay_hours FROM s2_stay_time_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, '停留时长统计', 's2_stay_time_statis', '停留时长统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_stay_time_statis_stay_hours","expr":"stay_hours","isCreateMetric":1,"name":"停留时长"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, page,user_name,stay_hours FROM s2_stay_time_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 'PVUV统计', 's2_pv_uv_statis', 'PVUV统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","expr":"pv","isCreateMetric":1,"name":"访问次数"},{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","expr":"uv","isCreateMetric":1,"name":"访问人数"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, user_name,page,1 as pv, user_name as uv FROM s2_pv_uv_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 'PVUV统计', 's2_pv_uv_statis', 'PVUV统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","expr":"pv","isCreateMetric":1,"name":"访问次数"},{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","expr":"uv","isCreateMetric":1,"name":"访问人数"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, user_name,page,1 as pv, user_name as uv FROM s2_pv_uv_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, '用户部门', 'user_department', '用户部门', 1, '{"dimensions":[{"bizName":"department","dateFormat":"yyyy-MM-dd","expr":"department","isCreateDimension":1,"name":"部门","type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[],"queryType":"sql_query","sqlQuery":"SELECT user_name,department FROM s2_user_department"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, '用户部门', 'user_department', '用户部门', 1, '{"dimensions":[{"bizName":"department","dateFormat":"yyyy-MM-dd","expr":"department","isCreateDimension":1,"name":"部门","type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[],"queryType":"sql_query","sqlQuery":"SELECT user_name,department FROM s2_user_department"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(4, 2, '艺人库', 'singer', '艺人库', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"act_area","dateFormat":"yyyy-MM-dd","expr":"act_area","isCreateDimension":1,"name":"活跃区域","type":"categorical"},{"bizName":"song_name","dateFormat":"yyyy-MM-dd","expr":"song_name","isCreateDimension":1,"name":"代表作","type":"categorical"},{"bizName":"genre","dateFormat":"yyyy-MM-dd","expr":"genre","isCreateDimension":1,"name":"风格","type":"categorical"}],"identifiers":[{"bizName":"singer_name","name":"歌手名","type":"primary"}],"measures":[{"agg":"sum","bizName":"music_down_cnt","expr":"down_cnt","isCreateMetric":1,"name":"下载量"},{"agg":"sum","bizName":"music_js_play_cnt","expr":"js_play_cnt","isCreateMetric":1,"name":"播放量"},{"agg":"sum","bizName":"music_favor_cnt","expr":"favor_cnt","isCreateMetric":1,"name":"收藏量"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date,singer_name,act_area,song_name,genre,js_play_cnt,down_cnt,favor_cnt FROM singer "}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, 1, 2, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, 1, 2, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 1, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 1, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, 2, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, 2, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(1, 1, 3, '部门', 'department', '部门', 1, 0, 'categorical', NULL, 'department', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY'); insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(1, 1, 3, '部门', 'department', '部门', 1, 0, 'categorical', NULL, 'department', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(2, 1, 1, '用户名', 'user_name', '用户名', 1, 0, 'primary', NULL, 'user_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY'); insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(2, 1, 1, '用户名', 'user_name', '用户名', 1, 0, 'primary', NULL, 'user_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(3, 1, 2, '页面', 'page', '页面', 1, 2, 'categorical', NULL, 'page', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY'); insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(3, 1, 2, '页面', 'page', '页面', 1, 2, 'categorical', NULL, 'page', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(4, 2, 4, '活跃区域', 'act_area', '活跃区域', 1, 2, 'categorical', NULL, 'act_area', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(5, 2, 4, '代表作', 'song_name', '代表作', 1, 2, 'categorical', NULL, 'song_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(6, 2, 4, '风格', 'genre', '风格', 1, 2, 'categorical', NULL, 'genre', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(7, 2, 4, '歌手名', 'singer_name', '歌手名', 1, 2, 'categorical', NULL, 'singer_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_domain (id, `name`, biz_name, parent_id, status, created_at, created_by, updated_at, updated_by, `admin`, admin_org, is_open, viewer, view_org) VALUES(1, '超音数', 'supersonic', 0, 1, '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin', 'admin', '', 0, 'admin,tom,jack', 'admin' ); insert into s2_domain (id, `name`, biz_name, parent_id, status, created_at, created_by, updated_at, updated_by, `admin`, admin_org, is_open, viewer, view_org) VALUES(1, '超音数', 'supersonic', 0, 1, '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin', 'admin', '', 0, 'admin,tom,jack', 'admin' );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(1, 1, '停留时长', 'stay_hours', '停留时长', 1, 2, 'expr', '{"expr":"s2_stay_time_statis_stay_hours","measures":[{"agg":"sum","expr":"stay_hours","isCreateMetric":1,"datasourceId":1,"bizName":"s2_stay_time_statis_stay_hours","name":"s2_stay_time_statis_stay_hours"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL ); insert into s2_domain (id, `name`, biz_name, parent_id, status, created_at, created_by, updated_at, updated_by, `admin`, admin_org, is_open, viewer, view_org) VALUES(2, '艺人库', 'singer', 0, 1, '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin', 'admin', '', 0, 'admin,tom,jack', 'admin' );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(2, 1, '访问次数', 'pv', '访问次数', 1, 0, 'expr', ' {"expr":"s2_pv_uv_statis_pv","measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","datasourceId":2,"expr":"pv","isCreateMetric":1,"name":"s2_pv_uv_statis_pv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL ); insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(1, 1, '停留时长', 'stay_hours', '停留时长', 1, 2, 'ATOMIC', '{"expr":"s2_stay_time_statis_stay_hours","measures":[{"agg":"sum","expr":"stay_hours","isCreateMetric":1,"datasourceId":1,"bizName":"s2_stay_time_statis_stay_hours","name":"s2_stay_time_statis_stay_hours"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(3, 1, '访问', 'uv', '访问', 1, 0, 'expr', ' {"expr":"s2_pv_uv_statis_uv","measures":[{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","datasourceId":2,"expr":"uv","isCreateMetric":1,"name":"s2_pv_uv_statis_uv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL ); insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(2, 1, '访问', 'pv', '访问', 1, 0, 'ATOMIC', ' {"expr":"s2_pv_uv_statis_pv","measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","datasourceId":2,"expr":"pv","isCreateMetric":1,"name":"s2_pv_uv_statis_pv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(3, 1, '访问人数', 'uv', '访问人数', 1, 0, 'ATOMIC', ' {"expr":"s2_pv_uv_statis_uv","measures":[{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","datasourceId":2,"expr":"uv","isCreateMetric":1,"name":"s2_pv_uv_statis_uv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(4, 2, '播放量', 'js_play_cnt', '播放量', 1, 2, 'ATOMIC', '{"expr":"music_js_play_cnt","measures":[{"agg":"sum","expr":"js_play_cnt","isCreateMetric":1,"datasourceId":4,"bizName":"music_js_play_cnt","name":"music_js_play_cnt"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(5, 2, '下载量', 'down_cnt', '下载量', 1, 0, 'ATOMIC', ' {"expr":"music_down_cnt","measures":[{"agg":"sum","bizName":"music_down_cnt","datasourceId":4,"expr":"down_cnt","isCreateMetric":1,"name":"music_down_cnt"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(6, 2, '收藏量', 'favor_cnt', '收藏量', 1, 0, 'ATOMIC', ' {"expr":"music_favor_cnt","measures":[{"agg":"sum","bizName":"music_favor_cnt","datasourceId":4,"expr":"favor_cnt","isCreateMetric":1,"name":"music_favor_cnt"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_available_date_info(`item_id` ,`type` ,`date_format` ,`start_date` ,`end_date` ,`unavailable_date` ,`created_at` ,`created_by` ,`updated_at` ,`updated_by` ) insert into s2_available_date_info(`item_id` ,`type` ,`date_format` ,`start_date` ,`end_date` ,`unavailable_date` ,`created_at` ,`created_by` ,`updated_at` ,`updated_by` )
values (1, 'dimension', 'yyyy-MM-dd', DATEADD('DAY', -28, CURRENT_DATE()), DATEADD('DAY', -1, CURRENT_DATE()), '[]', '2023-06-01', 'admin', '2023-06-01', 'admin'); values (1, 'dimension', 'yyyy-MM-dd', DATEADD('DAY', -28, CURRENT_DATE()), DATEADD('DAY', -1, CURRENT_DATE()), '[]', '2023-06-01', 'admin', '2023-06-01', 'admin');
@@ -39,6 +49,60 @@ insert into s2_user_department (user_name, department) values ('john','strategy'
insert into s2_user_department (user_name, department) values ('alice','sales'); insert into s2_user_department (user_name, department) values ('alice','sales');
insert into s2_user_department (user_name, department) values ('dean','marketing'); insert into s2_user_department (user_name, department) values ('dean','marketing');
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), 'lucy', 'p1'); INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), 'lucy', 'p1');
INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p1'); INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p1');

View File

@@ -211,6 +211,7 @@ CREATE TABLE IF NOT EXISTS `s2_available_date_info` (
`created_by` varchar(100) NOT NULL , `created_by` varchar(100) NOT NULL ,
`updated_at` TIMESTAMP NOT NULL , `updated_at` TIMESTAMP NOT NULL ,
`updated_by` varchar(100) NOT NULL , `updated_by` varchar(100) NOT NULL ,
`date_period` varchar(100) DEFAULT NULL ,
`status` INT DEFAULT '0', -- 1-in use 0 is normal, 1 is off the shelf, 2 is deleted `status` INT DEFAULT '0', -- 1-in use 0 is normal, 1 is off the shelf, 2 is deleted
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
); );
@@ -239,4 +240,16 @@ CREATE TABLE IF NOT EXISTS `s2_stay_time_statis` (
); );
COMMENT ON TABLE s2_stay_time_statis IS 's2_stay_time_statis_info'; COMMENT ON TABLE s2_stay_time_statis IS 's2_stay_time_statis_info';
CREATE TABLE IF NOT EXISTS `singer` (
`imp_date` varchar(200) NOT NULL,
`singer_name` varchar(200) NOT NULL,
`act_area` varchar(200) NOT NULL,
`song_name` varchar(200) NOT NULL,
`genre` varchar(200) NOT NULL,
`js_play_cnt` bigINT DEFAULT NULL,
`down_cnt` bigINT DEFAULT NULL,
`favor_cnt` bigINT DEFAULT NULL
);
COMMENT ON TABLE singer IS 'singer_info';

View File

@@ -1,2 +1,2 @@
export APP_NAME=chat-service export APP_NAME=chat-service
export MAIN_CLASS=com.tencent.supersonic.Launcher export MAIN_CLASS=com.tencent.supersonic.StandaloneLauncher

View File

@@ -5,7 +5,7 @@ baseDir=$(readlink -f $binDir/../)
confDir=$baseDir/conf confDir=$baseDir/conf
source ${baseDir}/bin/env.sh source ${baseDir}/bin/env.sh
commond=$1 command=$1
function start() function start()
{ {
@@ -33,7 +33,7 @@ function stop()
fi fi
} }
case "$commond" in case "$command" in
start) start)
echo -e "Starting $APP_NAME" echo -e "Starting $APP_NAME"
start start

View File

@@ -6,8 +6,8 @@ com.tencent.supersonic.chat.api.component.SchemaMapper=\
com.tencent.supersonic.chat.api.component.SemanticParser=\ com.tencent.supersonic.chat.api.component.SemanticParser=\
com.tencent.supersonic.chat.application.parser.DomainSemanticParser, \ com.tencent.supersonic.chat.application.parser.DomainSemanticParser, \
com.tencent.supersonic.chat.application.parser.TimeSemanticParser, \ com.tencent.supersonic.chat.application.parser.TimeSemanticParser, \
com.tencent.supersonic.chat.application.parser.AggregateSemanticParser com.tencent.supersonic.chat.application.parser.AggregateSemanticParser, \
# com.tencent.supersonic.chat.application.parser.LLMSemanticParser com.tencent.supersonic.chat.application.parser.LLMSemanticParser
com.tencent.supersonic.chat.api.component.SemanticLayer=\ com.tencent.supersonic.chat.api.component.SemanticLayer=\

View File

@@ -16,7 +16,7 @@ server:
port: 9080 port: 9080
authentication: authentication:
enable: false enable: true
exclude: exclude:
path: /api/auth/user/register,/api/auth/user/login path: /api/auth/user/register,/api/auth/user/login

View File

@@ -4,4 +4,16 @@ lucy _1_2 31
dean _1_2 36 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
陈奕迅 _2_7 100
林俊杰 _2_7 100
张碧晨 _2_7 100
程响 _2_7 100
Taylor#Swift _2_7 100
中国 _2_4 100
欧美 _2_4 100
流行 _2_6 100
爱情 _2_6 100
激情 _2_6 100
国风 _2_6 100

View File

@@ -4,7 +4,15 @@ insert into s2_user (id, `name`, password, display_name, email) values (2, 'jack
insert into s2_user (id, `name`, password, display_name, email) values (3, 'tom','123456','tom','tom@xx.com'); insert into s2_user (id, `name`, password, display_name, email) values (3, 'tom','123456','tom','tom@xx.com');
insert into s2_user (id, `name`, password, display_name, email) values (4, 'lucy','123456','lucy','lucy@xx.com'); insert into s2_user (id, `name`, password, display_name, email) values (4, 'lucy','123456','lucy','lucy@xx.com');
insert into s2_chat_config (`id` ,`domain_id` ,`default_metrics`,`visibility`,`entity_info` ,`dictionary_info`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` ) values (1,1,'[{"metricId":1,"unit":7,"period":"DAY"}]','{"blackDimIdList":[],"blackMetricIdList":[]}','{"entityIds":[2],"names":["用户","用户姓名"],"detailData":{"dimensionIds":[1,2],"metricIds":[2]}}','[{"itemId":1,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":2,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":3,"type":"DIMENSION","blackList":[],"isDictInfo":true}]','2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1); --insert into s2_chat_config (`id` ,`domain_id` ,`default_metrics`,`visibility`,`entity_info` ,`dictionary_info`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` ) values (1,1,'[{"metricId":1,"unit":7,"period":"DAY"}]','{"blackDimIdList":[],"blackMetricIdList":[]}','{"entityIds":[2],"names":["用户","用户姓名"],"detailData":{"dimensionIds":[1,2],"metricIds":[2]}}','[{"itemId":1,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":2,"type":"DIMENSION","blackList":[],"isDictInfo":true},{"itemId":3,"type":"DIMENSION","blackList":[],"isDictInfo":true}]','2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1);
insert into s2_chat_config (`id` ,`domain_id` ,`chat_detail_config`,`chat_agg_config`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` )
values (1,1,'{"visibility":{"blackDimIdList":[1],"blackMetricIdList":[2]},"knowledgeInfos":[{"itemId":2,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[1,2],"metricIds":[1],"unit":1,"period":"DAY"},"entity":null}',
'{"visibility":{"blackDimIdList":[3],"blackMetricIdList":[3]},"knowledgeInfos":[{"itemId":2,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[1,2],"metricIds":[1],"unit":1,"period":"DAY"}}',
'2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1);
insert into s2_chat_config (`id` ,`domain_id` ,`chat_detail_config`,`chat_agg_config`,`created_at`,`updated_at`,`created_by`,`updated_by`,`status` )
values (2,2,'{"visibility":{"blackDimIdList":[],"blackMetricIdList":[]},"knowledgeInfos":[{"itemId":7,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[4,5,6,7],"metricIds":[4],"unit":7,"period":"DAY"},"entity":{"entityId":1,"names":["歌手","艺人"]}}',
'{"visibility":{"blackDimIdList":[],"blackMetricIdList":[]},"knowledgeInfos":[{"itemId":7,"type":"DIMENSION","searchEnable":true}],"chatDefaultConfig":{"dimensionIds":[4,5,6,7],"metricIds":[4],"unit":7,"period":"DAY"}}',
'2023-05-24 18:00:00','2023-05-25 11:00:00','admin','admin',1);
insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (1, '超音数访问统计','2023-06-10 10:00:52.495','2023-06-10 10:00:52','admin','您好欢迎使用内容智能小Q','0','0'); insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (1, '超音数访问统计','2023-06-10 10:00:52.495','2023-06-10 10:00:52','admin','您好欢迎使用内容智能小Q','0','0');
insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (2, '用户访问统计','2023-06-10 10:01:04.528','2023-06-10 10:01:04','admin','您好欢迎使用内容智能小Q','0','0'); insert into s2_chat (chat_id, `chat_name`, create_time, last_time, creator,last_question,is_delete,is_top) values (2, '用户访问统计','2023-06-10 10:01:04.528','2023-06-10 10:01:04','admin','您好欢迎使用内容智能小Q','0','0');
@@ -22,19 +30,29 @@ insert into s2_chat_query (`question_id`,`create_time`,`query_text`,`user_name`,
-- semantic data -- semantic data
insert into s2_database (id, domain_id , `name`, description, `type` ,config ,created_at ,created_by ,updated_at ,updated_by) VALUES(1, 1, 'H2数据实例', '', 'h2', '{"password":"semantic","url":"jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false","userName":"root"}', '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin'); insert into s2_database (id, domain_id , `name`, description, `type` ,config ,created_at ,created_by ,updated_at ,updated_by) VALUES(1, 1, 'H2数据实例', '', 'h2', '{"password":"semantic","url":"jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false","userName":"root"}', '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin');
insert into s2_database (id, domain_id , `name`, description, `type` ,config ,created_at ,created_by ,updated_at ,updated_by) VALUES(2, 2, 'H2数据实例', '', 'h2', '{"password":"semantic","url":"jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false","userName":"root"}', '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, '停留时长统计', 's2_stay_time_statis', '停留时长统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_stay_time_statis_stay_hours","expr":"stay_hours","isCreateMetric":1,"name":"停留时长"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, page,user_name,stay_hours FROM s2_stay_time_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, '停留时长统计', 's2_stay_time_statis', '停留时长统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_stay_time_statis_stay_hours","expr":"stay_hours","isCreateMetric":1,"name":"停留时长"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, page,user_name,stay_hours FROM s2_stay_time_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 'PVUV统计', 's2_pv_uv_statis', 'PVUV统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","expr":"pv","isCreateMetric":1,"name":"访问次数"},{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","expr":"uv","isCreateMetric":1,"name":"访问人数"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, user_name,page,1 as pv, user_name as uv FROM s2_pv_uv_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 'PVUV统计', 's2_pv_uv_statis', 'PVUV统计', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"page","dateFormat":"yyyy-MM-dd","expr":"page","isCreateDimension":0,"type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","expr":"pv","isCreateMetric":1,"name":"访问次数"},{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","expr":"uv","isCreateMetric":1,"name":"访问人数"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date, user_name,page,1 as pv, user_name as uv FROM s2_pv_uv_statis"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, '用户部门', 'user_department', '用户部门', 1, '{"dimensions":[{"bizName":"department","dateFormat":"yyyy-MM-dd","expr":"department","isCreateDimension":1,"name":"部门","type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[],"queryType":"sql_query","sqlQuery":"SELECT user_name,department FROM s2_user_department"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, '用户部门', 'user_department', '用户部门', 1, '{"dimensions":[{"bizName":"department","dateFormat":"yyyy-MM-dd","expr":"department","isCreateDimension":1,"name":"部门","type":"categorical"}],"identifiers":[{"bizName":"user_name","name":"用户名","type":"primary"}],"measures":[],"queryType":"sql_query","sqlQuery":"SELECT user_name,department FROM s2_user_department"}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource (id , domain_id, `name`, biz_name, description, database_id ,datasource_detail, created_at, created_by, updated_at, updated_by ) VALUES(4, 2, '艺人库', 'singer', '艺人库', 1, '{"dimensions":[{"bizName":"imp_date","dateFormat":"yyyy-MM-dd","expr":"imp_date","isCreateDimension":0,"type":"time","typeParams":{"isPrimary":"true","timeGranularity":"day"}},{"bizName":"act_area","dateFormat":"yyyy-MM-dd","expr":"act_area","isCreateDimension":1,"name":"活跃区域","type":"categorical"},{"bizName":"song_name","dateFormat":"yyyy-MM-dd","expr":"song_name","isCreateDimension":1,"name":"代表作","type":"categorical"},{"bizName":"genre","dateFormat":"yyyy-MM-dd","expr":"genre","isCreateDimension":1,"name":"风格","type":"categorical"}],"identifiers":[{"bizName":"singer_name","name":"歌手名","type":"primary"}],"measures":[{"agg":"sum","bizName":"music_down_cnt","expr":"down_cnt","isCreateMetric":1,"name":"下载量"},{"agg":"sum","bizName":"music_js_play_cnt","expr":"js_play_cnt","isCreateMetric":1,"name":"播放量"},{"agg":"sum","bizName":"music_favor_cnt","expr":"favor_cnt","isCreateMetric":1,"name":"收藏量"}],"queryType":"sql_query","sqlQuery":"SELECT imp_date,singer_name,act_area,song_name,genre,js_play_cnt,down_cnt,favor_cnt FROM singer "}', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, 1, 2, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(1, 1, 1, 2, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 1, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(2, 1, 1, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, 2, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin'); insert into s2_datasource_rela (id , domain_id, `datasource_from`, datasource_to, join_key, created_at, created_by, updated_at, updated_by ) VALUES(3, 1, 2, 3, 'user_name', '2023-05-25 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(1, 1, 3, '部门', 'department', '部门', 1, 0, 'categorical', NULL, 'department', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY'); insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(1, 1, 3, '部门', 'department', '部门', 1, 0, 'categorical', NULL, 'department', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(2, 1, 1, '用户名', 'user_name', '用户名', 1, 0, 'primary', NULL, 'user_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY'); insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(2, 1, 1, '用户名', 'user_name', '用户名', 1, 0, 'primary', NULL, 'user_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(3, 1, 2, '页面', 'page', '页面', 1, 2, 'categorical', NULL, 'page', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY'); insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(3, 1, 2, '页面', 'page', '页面', 1, 2, 'categorical', NULL, 'page', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(4, 2, 4, '活跃区域', 'act_area', '活跃区域', 1, 2, 'categorical', NULL, 'act_area', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(5, 2, 4, '代表作', 'song_name', '代表作', 1, 2, 'categorical', NULL, 'song_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(6, 2, 4, '风格', 'genre', '风格', 1, 2, 'categorical', NULL, 'genre', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_dimension (id , domain_id, datasource_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, expr, created_at, created_by, updated_at, updated_by, semantic_type) VALUES(7, 2, 4, '歌手名', 'singer_name', '歌手名', 1, 2, 'categorical', NULL, 'singer_name', '2023-05-24 00:00:00', 'admin', '2023-05-25 00:00:00', 'admin', 'CATEGORY');
insert into s2_domain (id, `name`, biz_name, parent_id, status, created_at, created_by, updated_at, updated_by, `admin`, admin_org, is_open, viewer, view_org) VALUES(1, '超音数', 'supersonic', 0, 1, '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin', 'admin', '', 0, 'admin,tom,jack', 'admin' ); insert into s2_domain (id, `name`, biz_name, parent_id, status, created_at, created_by, updated_at, updated_by, `admin`, admin_org, is_open, viewer, view_org) VALUES(1, '超音数', 'supersonic', 0, 1, '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin', 'admin', '', 0, 'admin,tom,jack', 'admin' );
insert into s2_domain (id, `name`, biz_name, parent_id, status, created_at, created_by, updated_at, updated_by, `admin`, admin_org, is_open, viewer, view_org) VALUES(2, '艺人库', 'singer', 0, 1, '2023-05-24 00:00:00', 'admin', '2023-05-24 00:00:00', 'admin', 'admin', '', 0, 'admin,tom,jack', 'admin' );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(1, 1, '停留时长', 'stay_hours', '停留时长', 1, 2, 'expr', '{"expr":"s2_stay_time_statis_stay_hours","measures":[{"agg":"sum","expr":"stay_hours","isCreateMetric":1,"datasourceId":1,"bizName":"s2_stay_time_statis_stay_hours","name":"s2_stay_time_statis_stay_hours"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL ); insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(1, 1, '停留时长', 'stay_hours', '停留时长', 1, 2, 'expr', '{"expr":"s2_stay_time_statis_stay_hours","measures":[{"agg":"sum","expr":"stay_hours","isCreateMetric":1,"datasourceId":1,"bizName":"s2_stay_time_statis_stay_hours","name":"s2_stay_time_statis_stay_hours"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(2, 1, '访问次数', 'pv', '访问次数', 1, 0, 'expr', ' {"expr":"s2_pv_uv_statis_pv","measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","datasourceId":2,"expr":"pv","isCreateMetric":1,"name":"s2_pv_uv_statis_pv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL ); insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(2, 1, '访问次数', 'pv', '访问次数', 1, 0, 'expr', ' {"expr":"s2_pv_uv_statis_pv","measures":[{"agg":"sum","bizName":"s2_pv_uv_statis_pv","datasourceId":2,"expr":"pv","isCreateMetric":1,"name":"s2_pv_uv_statis_pv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(3, 1, '访问人数', 'uv', '访问人数', 1, 0, 'expr', ' {"expr":"s2_pv_uv_statis_uv","measures":[{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","datasourceId":2,"expr":"uv","isCreateMetric":1,"name":"s2_pv_uv_statis_uv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL ); insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(3, 1, '访问人数', 'uv', '访问人数', 1, 0, 'expr', ' {"expr":"s2_pv_uv_statis_uv","measures":[{"agg":"count_distinct","bizName":"s2_pv_uv_statis_uv","datasourceId":2,"expr":"uv","isCreateMetric":1,"name":"s2_pv_uv_statis_uv"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(4, 2, '播放量', 'js_play_cnt', '播放量', 1, 2, 'expr', '{"expr":"music_js_play_cnt","measures":[{"agg":"sum","expr":"js_play_cnt","isCreateMetric":1,"datasourceId":4,"bizName":"music_js_play_cnt","name":"music_js_play_cnt"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(5, 2, '下载量', 'down_cnt', '下载量', 1, 0, 'expr', ' {"expr":"music_down_cnt","measures":[{"agg":"sum","bizName":"music_down_cnt","datasourceId":4,"expr":"down_cnt","isCreateMetric":1,"name":"music_down_cnt"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_metric (id, domain_id, `name`, biz_name, description, status, sensitive_level, `type`, type_params, created_at, created_by, updated_at, updated_by, data_format_type, data_format) VALUES(6, 2, '收藏量', 'favor_cnt', '收藏量', 1, 0, 'expr', ' {"expr":"music_favor_cnt","measures":[{"agg":"sum","bizName":"music_favor_cnt","datasourceId":4,"expr":"favor_cnt","isCreateMetric":1,"name":"music_favor_cnt"}]}' , '2023-05-24 17:00:00', 'admin', '2023-05-25 00:00:00', 'admin', NULL, NULL );
insert into s2_available_date_info(`item_id` ,`type` ,`date_format` ,`start_date` ,`end_date` ,`unavailable_date` ,`created_at` ,`created_by` ,`updated_at` ,`updated_by` ) insert into s2_available_date_info(`item_id` ,`type` ,`date_format` ,`start_date` ,`end_date` ,`unavailable_date` ,`created_at` ,`created_by` ,`updated_at` ,`updated_by` )
values (1, 'dimension', 'yyyy-MM-dd', DATEADD('DAY', -28, CURRENT_DATE()), DATEADD('DAY', -1, CURRENT_DATE()), '[]', '2023-06-01', 'admin', '2023-06-01', 'admin'); values (1, 'dimension', 'yyyy-MM-dd', DATEADD('DAY', -28, CURRENT_DATE()), DATEADD('DAY', -1, CURRENT_DATE()), '[]', '2023-06-01', 'admin', '2023-06-01', 'admin');
@@ -48,13 +66,64 @@ values (1, '{"domainId":"1","name":"admin-permission","groupId":1,"authRules":[{
insert into s2_auth_groups (group_id, config) insert into s2_auth_groups (group_id, config)
values (2, '{"domainId":"1","name":"tom_sales_permission","groupId":2,"authRules":[{"metrics":["stay_hours"],"dimensions":["page"]}],"dimensionFilters":["department in (''sales'')"],"dimensionFilterDescription":"开通 tom sales部门权限", "authorizedUsers":["tom"],"authorizedDepartmentIds":[]}'); values (2, '{"domainId":"1","name":"tom_sales_permission","groupId":2,"authRules":[{"metrics":["stay_hours"],"dimensions":["page"]}],"dimensionFilters":["department in (''sales'')"],"dimensionFilterDescription":"开通 tom sales部门权限", "authorizedUsers":["tom"],"authorizedDepartmentIds":[]}');
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '周杰伦', '中国','青花瓷','流行',1000000,1000000,1000000);
-- insert into s2_user (id, `name`, password, display_name, email) values (1, 'admin','admin','admin','admin@xx.com'); INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
-- insert into s2_user (id, `name`, password, display_name, email) values (2, 'jack','123456','jack','jack@xx.com'); INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
-- insert into s2_user (id, `name`, password, display_name, email) values (3, 'tom','123456','tom','tom@xx.com'); INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
-- insert into s2_user (id, `name`, password, display_name, email) values (4, 'lucy','123456','lucy','lucy@xx.com'); INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '陈奕迅', '中国','爱情转移','激情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '林俊杰', '中国','美人鱼','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '张碧晨', '中国','光的方向','流行',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), '程响', '中国','人间烟火','国风',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
INSERT INTO singer (imp_date,singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'Taylor Swift
', '欧美','Love Story','爱情',1000000,1000000,1000000);
---demo data for semantic and chat ---demo data for semantic and chat
insert into s2_user_department (user_name, department) values ('jack','HR');
insert into s2_user_department (user_name, department) values ('jack','HR'); insert into s2_user_department (user_name, department) values ('jack','HR');
insert into s2_user_department (user_name, department) values ('tom','sales'); insert into s2_user_department (user_name, department) values ('tom','sales');
insert into s2_user_department (user_name, department) values ('lucy','marketing'); insert into s2_user_department (user_name, department) values ('lucy','marketing');

View File

@@ -8,7 +8,7 @@ CREATE TABLE IF NOT EXISTS `s2_chat_context`
`semantic_parse` LONGVARCHAR DEFAULT NULL , -- parse data `semantic_parse` LONGVARCHAR DEFAULT NULL , -- parse data
`ext_data` LONGVARCHAR DEFAULT NULL , -- extend data `ext_data` LONGVARCHAR DEFAULT NULL , -- extend data
PRIMARY KEY (`chat_id`) PRIMARY KEY (`chat_id`)
); );
CREATE TABLE IF NOT EXISTS `s2_chat` CREATE TABLE IF NOT EXISTS `s2_chat`
( (
@@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS `s2_chat`
`is_delete` INT DEFAULT '0' COMMENT 'is deleted', `is_delete` INT DEFAULT '0' COMMENT 'is deleted',
`is_top` INT DEFAULT '0' COMMENT 'is top', `is_top` INT DEFAULT '0' COMMENT 'is top',
PRIMARY KEY (`chat_id`) PRIMARY KEY (`chat_id`)
) ; ) ;
CREATE TABLE `s2_chat_query` CREATE TABLE `s2_chat_query`
@@ -39,33 +39,30 @@ CREATE TABLE `s2_chat_query`
); );
CREATE TABLE IF NOT EXISTS `s2_chat_config` ( CREATE TABLE IF NOT EXISTS `s2_chat_config` (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT DEFAULT NULL , `domain_id` INT DEFAULT NULL ,
`default_metrics` varchar(655) DEFAULT NULL, `chat_detail_config` varchar(655) ,
`visibility` varchar(655) , -- invisible dimension metric information `chat_agg_config` varchar(655) ,
`entity_info` varchar(655) ,
`dictionary_info` varchar(655) , -- dictionary-related dimension setting information
`created_at` TIMESTAMP NOT NULL , `created_at` TIMESTAMP NOT NULL ,
`updated_at` TIMESTAMP NOT NULL , `updated_at` TIMESTAMP NOT NULL ,
`created_by` varchar(100) NOT NULL , `created_by` varchar(100) NOT NULL ,
`updated_by` varchar(100) NOT NULL , `updated_by` varchar(100) NOT NULL ,
`status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted `status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ; ) ;
COMMENT ON TABLE s2_chat_config IS 'chat config information table '; COMMENT ON TABLE s2_chat_config IS 'chat config information table ';
CREATE TABLE IF NOT EXISTS `s2_dictionary` ( CREATE TABLE IF NOT EXISTS `s2_dictionary` (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL , `domain_id` INT NOT NULL ,
`dim_value_infos` LONGVARCHAR , -- dimension value setting information `dim_value_infos` LONGVARCHAR , -- dimension value setting information
`created_at` TIMESTAMP NOT NULL , `created_at` TIMESTAMP NOT NULL ,
`updated_at` TIMESTAMP NOT NULL , `updated_at` TIMESTAMP NOT NULL ,
`created_by` varchar(100) NOT NULL , `created_by` varchar(100) NOT NULL ,
`updated_by` varchar(100) DEFAULT NULL , `updated_by` varchar(100) DEFAULT NULL ,
`status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted `status` INT NOT NULL DEFAULT '0' , -- domain extension information status : 0 is normal, 1 is off the shelf, 2 is deleted
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
@@ -75,19 +72,19 @@ COMMENT ON TABLE s2_dictionary IS 'dictionary configuration information table';
CREATE TABLE IF NOT EXISTS `s2_dictionary_task` ( CREATE TABLE IF NOT EXISTS `s2_dictionary_task` (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL , -- task name `name` varchar(255) NOT NULL , -- task name
`description` varchar(255) , `description` varchar(255) ,
`command`LONGVARCHAR NOT NULL , -- task Request Parameters `command`LONGVARCHAR NOT NULL , -- task Request Parameters
`command_md5` varchar(255) NOT NULL , -- task Request Parameters md5 `command_md5` varchar(255) NOT NULL , -- task Request Parameters md5
`status` INT NOT NULL , -- the final status of the task `status` INT NOT NULL , -- the final status of the task
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP , `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ,
`created_by` varchar(100) NOT NULL , `created_by` varchar(100) NOT NULL ,
`progress` DOUBLE default 0.00 , -- task real-time progress `progress` DOUBLE default 0.00 , -- task real-time progress
`elapsed_ms` bigINT DEFAULT NULL , -- the task takes time in milliseconds `elapsed_ms` bigINT DEFAULT NULL , -- the task takes time in milliseconds
`message` LONGVARCHAR , -- remark related information `message` LONGVARCHAR , -- remark related information
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
); );
COMMENT ON TABLE s2_dictionary_task IS 'dictionary task information table'; COMMENT ON TABLE s2_dictionary_task IS 'dictionary task information table';
@@ -306,6 +303,7 @@ CREATE TABLE IF NOT EXISTS `s2_available_date_info` (
`created_by` varchar(100) NOT NULL , `created_by` varchar(100) NOT NULL ,
`updated_at` TIMESTAMP NOT NULL , `updated_at` TIMESTAMP NOT NULL ,
`updated_by` varchar(100) NOT NULL , `updated_by` varchar(100) NOT NULL ,
`date_period` varchar(100) DEFAULT NULL ,
`status` INT DEFAULT '0', -- 1-in use 0 is normal, 1 is off the shelf, 2 is deleted `status` INT DEFAULT '0', -- 1-in use 0 is normal, 1 is off the shelf, 2 is deleted
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
); );
@@ -334,6 +332,18 @@ CREATE TABLE IF NOT EXISTS `s2_stay_time_statis` (
); );
COMMENT ON TABLE s2_stay_time_statis IS 's2_stay_time_statis_info'; COMMENT ON TABLE s2_stay_time_statis IS 's2_stay_time_statis_info';
CREATE TABLE IF NOT EXISTS `singer` (
`imp_date` varchar(200) NOT NULL,
`singer_name` varchar(200) NOT NULL,
`act_area` varchar(200) NOT NULL,
`song_name` varchar(200) NOT NULL,
`genre` varchar(200) NOT NULL,
`js_play_cnt` bigINT DEFAULT NULL,
`down_cnt` bigINT DEFAULT NULL,
`favor_cnt` bigINT DEFAULT NULL
);
COMMENT ON TABLE singer IS 'singer_info';

Some files were not shown because too many files have changed in this diff Show More