mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-10 11:07:06 +00:00
[improvement][project] supersonic 0.6.0 version update (#16)
Co-authored-by: lexluo <lexluo@tencent.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,4 +14,4 @@ assembly/runtime/*
|
||||
*.umi/
|
||||
/assembly/deploy
|
||||
/runtime
|
||||
.flattened-pom.xml
|
||||
**/.flattened-pom.xml
|
||||
11
CHANGELOG
11
CHANGELOG
@@ -8,3 +8,14 @@ davinci 0.3.0 change log
|
||||
7) optimize css style
|
||||
8) optimize filter
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
|
||||
<img src="./docs/images/supersonic_demo.gif" align="center"/>
|
||||
|
||||
## 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:
|
||||
|
||||
|
||||
<img src="./docs/images/supersonic_components.png" height="80%" width="80%" align="center"/>
|
||||
|
||||
|
||||
### Chat Layer
|
||||
|
||||
The chat layer contains four core components:
|
||||
|
||||
12
assembly/bin/build-chat.sh
Executable file
12
assembly/bin/build-chat.sh
Executable 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
|
||||
|
||||
@@ -7,14 +7,13 @@ buildDir=$baseDir/build
|
||||
|
||||
cd $baseDir
|
||||
|
||||
#1. build semantic chat service
|
||||
#1. build semantic service
|
||||
rm -fr ${buildDir}/*.tar.gz
|
||||
rm -fr dist
|
||||
|
||||
mvn -f $baseDir/../ clean package -DskipTests
|
||||
|
||||
#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
|
||||
|
||||
#3. build webapp
|
||||
35
assembly/bin/start-chat.sh
Executable file
35
assembly/bin/start-chat.sh
Executable 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
|
||||
|
||||
@@ -14,23 +14,23 @@ rm -fr ${runtimeDir}/*
|
||||
#2. package lib
|
||||
|
||||
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
|
||||
|
||||
tar -zxvf ${buildDir}/supersonic-webapp.tar.gz -C ${buildDir}
|
||||
|
||||
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-chat/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
|
||||
sh ${runtimeDir}/supersonic-semantic/bin/service.sh restart
|
||||
sleep 5
|
||||
sh ${runtimeDir}/supersonic-chat/bin/service.sh restart
|
||||
|
||||
|
||||
@@ -26,5 +26,7 @@ cp -fr ${buildDir}/supersonic-webapp/* ${runtimeDir}/supersonic-standalone/weba
|
||||
rm -fr ${buildDir}/supersonic-webapp
|
||||
|
||||
#3. start service
|
||||
#start standalone service
|
||||
sh ${runtimeDir}/supersonic-standalone/bin/service.sh restart
|
||||
|
||||
#start llm service
|
||||
sh ${runtimeDir}/supersonic-standalone/llm/bin/service.sh restart
|
||||
@@ -28,6 +28,12 @@
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/../../chat/core/src/main/python</directory>
|
||||
<outputDirectory>llm</outputDirectory>
|
||||
<fileMode>0777</fileMode>
|
||||
<directoryMode>0755</directoryMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<dependencySets>
|
||||
|
||||
@@ -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.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
|
||||
import com.tencent.supersonic.auth.authentication.application.UserServiceImpl;
|
||||
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
|
||||
@@ -27,11 +28,12 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
|
||||
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
|
||||
if (!authenticationConfig.isEnabled()) {
|
||||
setFakerUser(request);
|
||||
return true;
|
||||
}
|
||||
if (isInternalRequest(request)) {
|
||||
String token = userTokenUtils.generateAdminToken();
|
||||
reflectSetparam(request, authenticationConfig.getTokenHttpHeaderKey(), token);
|
||||
setFakerUser(request);
|
||||
return true;
|
||||
}
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
Method method = handlerMethod.getMethod();
|
||||
@@ -47,15 +49,25 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
|
||||
UserWithPassword user = userTokenUtils.getUserWithPassword(request);
|
||||
if (StringUtils.isNotBlank(user.getName())) {
|
||||
ThreadContext threadContext = ThreadContext.builder()
|
||||
.token(request.getHeader(authenticationConfig.getTokenHttpHeaderKey()))
|
||||
.userName(user.getName())
|
||||
.build();
|
||||
s2ThreadContext.set(threadContext);
|
||||
setContext(user.getName(), request);
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
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.semantic.api.core.response.DomainSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.core.response.QueryResultWithSchemaResp;
|
||||
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.*;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
|
||||
@@ -26,8 +28,24 @@ public interface SemanticLayer {
|
||||
|
||||
QueryResultWithSchemaResp queryBySql(QuerySqlReq querySqlReq, User user);
|
||||
|
||||
DomainSchemaResp getDomainSchemaInfo(Long domain);
|
||||
DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable);
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
@@ -3,32 +3,25 @@ package com.tencent.supersonic.chat.application;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
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.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.pojo.config.*;
|
||||
import com.tencent.supersonic.chat.domain.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
|
||||
import com.tencent.supersonic.common.util.json.JsonUtil;
|
||||
import com.tencent.supersonic.common.pojo.SchemaItem;
|
||||
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.DomainSchemaResp;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@@ -40,33 +33,31 @@ import org.springframework.util.CollectionUtils;
|
||||
@Service
|
||||
public class ConfigServiceImpl implements ConfigService {
|
||||
|
||||
private final ChatConfigRepository chaConfigRepository;
|
||||
private final ChatConfigRepository chatConfigRepository;
|
||||
private final ChatConfigUtils chatConfigUtils;
|
||||
private final DefaultSemanticInternalUtils defaultSemanticUtils;
|
||||
private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
|
||||
|
||||
public ConfigServiceImpl(ChatConfigRepository chaConfigRepository,
|
||||
ChatConfigUtils chatConfigUtils,
|
||||
@Lazy DefaultSemanticInternalUtils defaultSemanticUtils) {
|
||||
this.chaConfigRepository = chaConfigRepository;
|
||||
public ConfigServiceImpl(ChatConfigRepository chatConfigRepository,
|
||||
ChatConfigUtils chatConfigUtils) {
|
||||
this.chatConfigRepository = chatConfigRepository;
|
||||
this.chatConfigUtils = chatConfigUtils;
|
||||
this.defaultSemanticUtils = defaultSemanticUtils;
|
||||
}
|
||||
|
||||
@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));
|
||||
duplicateCheck(configBaseCmd.getDomainId());
|
||||
permissionCheckLogic(configBaseCmd.getDomainId(), user.getName());
|
||||
ChatConfig chaConfig = chatConfigUtils.newChatConfig(configBaseCmd, user);
|
||||
chaConfigRepository.createConfig(chaConfig);
|
||||
return chaConfig.getDomainId();
|
||||
Long id = chatConfigRepository.createConfig(chaConfig);
|
||||
return id;
|
||||
}
|
||||
|
||||
private void duplicateCheck(Long domainId) {
|
||||
ChatConfigFilter filter = new ChatConfigFilter();
|
||||
filter.setDomainId(domainId);
|
||||
List<ChatConfigInfo> chaConfigDescList = chaConfigRepository.getChatConfig(filter);
|
||||
List<ChatConfigResp> chaConfigDescList = chatConfigRepository.getChatConfig(filter);
|
||||
if (!CollectionUtils.isEmpty(chaConfigDescList)) {
|
||||
throw new RuntimeException("chat config existed, no need to add repeatedly");
|
||||
}
|
||||
@@ -74,16 +65,16 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
|
||||
|
||||
@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));
|
||||
if (Objects.isNull(configEditCmd) || Objects.isNull(configEditCmd.getId()) && Objects.isNull(
|
||||
configEditCmd.getDomainId())) {
|
||||
throw new RuntimeException("editConfig, id and domainId are not allowed to be empty at the same time");
|
||||
}
|
||||
permissionCheckLogic(configEditCmd.getDomainId(), user.getName());
|
||||
ChatConfig chaConfig = chatConfigUtils.editChaConfig(configEditCmd, user);
|
||||
chaConfigRepository.updateConfig(chaConfig);
|
||||
return configEditCmd.getDomainId();
|
||||
ChatConfig chaConfig = chatConfigUtils.editChatConfig(configEditCmd, user);
|
||||
chatConfigRepository.updateConfig(chaConfig);
|
||||
return configEditCmd.getId();
|
||||
}
|
||||
|
||||
|
||||
@@ -96,98 +87,34 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
}
|
||||
|
||||
@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));
|
||||
List<ChatConfigInfo> chaConfigDescList = chaConfigRepository.getChatConfig(filter);
|
||||
List<ChatConfigResp> chaConfigDescList = chatConfigRepository.getChatConfig(filter);
|
||||
return chaConfigDescList;
|
||||
}
|
||||
|
||||
|
||||
public ChatConfigInfo fetchConfigByDomainId(Long domainId) {
|
||||
return chaConfigRepository.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;
|
||||
@Override
|
||||
public ChatConfigResp fetchConfigByDomainId(Long domainId) {
|
||||
return chatConfigRepository.getConfigByDomainId(domainId);
|
||||
}
|
||||
|
||||
|
||||
public List<DefaultMetric> fetchDefaultMetricDescByDomainId(Long domainId) {
|
||||
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
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,
|
||||
private ItemVisibilityInfo fetchVisibilityDescByConfig(ItemVisibility visibility,
|
||||
DomainSchemaResp domainSchemaDesc) {
|
||||
ItemVisibilityInfo itemVisibilityDesc = new ItemVisibilityInfo();
|
||||
Long domainId = chatConfigDesc.getDomainId();
|
||||
|
||||
List<Long> dimIdAllList = chatConfigUtils.generateAllDimIdList(domainSchemaDesc);
|
||||
List<Long> metricIdAllList = chatConfigUtils.generateAllMetricIdList(domainSchemaDesc);
|
||||
|
||||
List<Long> blackDimIdList = new ArrayList<>();
|
||||
List<Long> blackMetricIdList = new ArrayList<>();
|
||||
if (Objects.nonNull(chatConfigDesc.getVisibility())) {
|
||||
if (!CollectionUtils.isEmpty(chatConfigDesc.getVisibility().getBlackDimIdList())) {
|
||||
blackDimIdList.addAll(chatConfigDesc.getVisibility().getBlackDimIdList());
|
||||
if (Objects.nonNull(visibility)) {
|
||||
if (!CollectionUtils.isEmpty(visibility.getBlackDimIdList())) {
|
||||
blackDimIdList.addAll(visibility.getBlackDimIdList());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(chatConfigDesc.getVisibility().getBlackMetricIdList())) {
|
||||
blackMetricIdList.addAll(chatConfigDesc.getVisibility().getBlackMetricIdList());
|
||||
if (!CollectionUtils.isEmpty(visibility.getBlackMetricIdList())) {
|
||||
blackMetricIdList.addAll(visibility.getBlackMetricIdList());
|
||||
}
|
||||
}
|
||||
List<Long> whiteMetricIdList = metricIdAllList.stream().filter(id -> !blackMetricIdList.contains(id))
|
||||
@@ -204,29 +131,108 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatConfigRichInfo getConfigRichInfo(Long domainId) {
|
||||
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
ChatConfigRichInfo chaConfigRichDesc = new ChatConfigRichInfo();
|
||||
ChatConfigInfo chatConfigDesc = chaConfigRepository.getConfigByDomainId(domainId);
|
||||
if (Objects.isNull(chatConfigDesc)) {
|
||||
public ChatConfigRichResp getConfigRichInfo(Long domainId) {
|
||||
ChatConfigRichResp chatConfigRichResp = new ChatConfigRichResp();
|
||||
ChatConfigResp chatConfigResp = chatConfigRepository.getConfigByDomainId(domainId);
|
||||
if (Objects.isNull(chatConfigResp)) {
|
||||
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);
|
||||
chaConfigRichDesc.setBizName(domainSchemaInfo.getBizName());
|
||||
chaConfigRichDesc.setName(domainSchemaInfo.getName());
|
||||
SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
DomainSchemaResp domainSchemaInfo = semanticLayer.getDomainSchemaInfo(domainId, false);
|
||||
chatConfigRichResp.setBizName(domainSchemaInfo.getBizName());
|
||||
chatConfigRichResp.setDomainName(domainSchemaInfo.getName());
|
||||
|
||||
chaConfigRichDesc.setKnowledgeInfos(
|
||||
fillKnowledgeBizName(chaConfigRichDesc.getKnowledgeInfos(), domainSchemaInfo));
|
||||
chaConfigRichDesc.setDefaultMetrics(fetchDefaultMetricDescByConfig(chatConfigDesc, domainSchemaInfo));
|
||||
chaConfigRichDesc.setVisibility(fetchVisibilityDescByConfig(chatConfigDesc, domainSchemaInfo));
|
||||
chaConfigRichDesc.setEntity(fetchEntityDescByConfig(chatConfigDesc, domainSchemaInfo));
|
||||
chatConfigRichResp.setChatAggRichConfig(fillChatAggRichConfig(domainSchemaInfo, chatConfigResp));
|
||||
chatConfigRichResp.setChatDetailRichConfig(fillChatDetailRichConfig(domainSchemaInfo, chatConfigRichResp, chatConfigResp));
|
||||
|
||||
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,
|
||||
DomainSchemaResp domainSchemaInfo) {
|
||||
if (CollectionUtils.isEmpty(knowledgeInfos)) {
|
||||
@@ -240,26 +246,17 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
if (Objects.nonNull(dimSchemaResp)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatConfigRichInfo> getAllChatRichConfig() {
|
||||
List<ChatConfigRichInfo> chatConfigRichInfoList = new ArrayList<>();
|
||||
List<DomainResp> domainRespList = defaultSemanticUtils.getDomainListForAdmin();
|
||||
public List<ChatConfigRichResp> getAllChatRichConfig() {
|
||||
List<ChatConfigRichResp> chatConfigRichInfoList = new ArrayList<>();
|
||||
List<DomainResp> domainRespList = semanticLayer.getDomainListForAdmin();
|
||||
domainRespList.stream().forEach(domainResp -> {
|
||||
ChatConfigRichInfo chatConfigRichInfo = getConfigRichInfo(domainResp.getId());
|
||||
ChatConfigRichResp chatConfigRichInfo = getConfigRichInfo(domainResp.getId());
|
||||
if (Objects.nonNull(chatConfigRichInfo)) {
|
||||
chatConfigRichInfoList.add(chatConfigRichInfo);
|
||||
}
|
||||
|
||||
@@ -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.Filter;
|
||||
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.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
|
||||
import com.tencent.supersonic.chat.domain.utils.SchemaInfoConverter;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
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.query.enums.FilterOperatorEnum;
|
||||
import java.util.ArrayList;
|
||||
@@ -37,7 +36,7 @@ public class DomainEntityService {
|
||||
private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
|
||||
@Autowired
|
||||
private DefaultSemanticInternalUtils defaultSemanticUtils;
|
||||
private ConfigServiceImpl configService;
|
||||
|
||||
public EntityInfo getEntityInfo(SemanticParseInfo parseInfo, User user) {
|
||||
if (parseInfo != null && parseInfo.getDomainId() > 0) {
|
||||
@@ -77,27 +76,36 @@ public class DomainEntityService {
|
||||
}
|
||||
|
||||
public EntityInfo getEntityInfo(Long domain) {
|
||||
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(domain);
|
||||
return getEntityInfo(chaConfigRichDesc.getEntity());
|
||||
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(domain);
|
||||
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())) {
|
||||
EntityRichInfo entityDesc = chaConfigRichDesc.getChatDetailRichConfig().getEntity();
|
||||
if (entityDesc != null && Objects.nonNull(chaConfigRichDesc.getDomainId())) {
|
||||
DomainInfo domainInfo = new DomainInfo();
|
||||
domainInfo.setItemId(Integer.valueOf(entityDesc.getDomainId().intValue()));
|
||||
domainInfo.setName(entityDesc.getDomainName());
|
||||
domainInfo.setItemId(Integer.valueOf(chaConfigRichDesc.getDomainId().intValue()));
|
||||
domainInfo.setName(chaConfigRichDesc.getDomainName());
|
||||
domainInfo.setWords(entityDesc.getNames());
|
||||
domainInfo.setBizName(entityDesc.getDomainBizName());
|
||||
if (entityDesc.getEntityIds().size() > 0) {
|
||||
domainInfo.setPrimaryEntityBizName(entityDesc.getEntityIds().get(0).getBizName());
|
||||
domainInfo.setBizName(chaConfigRichDesc.getBizName());
|
||||
if (Objects.nonNull(entityDesc.getDimItem())) {
|
||||
domainInfo.setPrimaryEntityBizName(entityDesc.getDimItem().getBizName());
|
||||
}
|
||||
|
||||
entityInfo.setDomainInfo(domainInfo);
|
||||
List<DataInfo> dimensions = 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())
|
||||
&& Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig())) {
|
||||
ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig();
|
||||
if(!CollectionUtils.isEmpty(chatDefaultConfig.getDimensions())){
|
||||
for (SchemaItem dimensionDesc : chatDefaultConfig.getDimensions()) {
|
||||
DataInfo mainEntityDimension = new DataInfo();
|
||||
mainEntityDimension.setItemId(dimensionDesc.getId().intValue());
|
||||
mainEntityDimension.setName(dimensionDesc.getName());
|
||||
@@ -105,7 +113,10 @@ public class DomainEntityService {
|
||||
dimensions.add(mainEntityDimension);
|
||||
}
|
||||
entityInfo.setDimensions(dimensions);
|
||||
for (MetricSchemaResp metricDesc : entityDesc.getEntityInternalDetailDesc().getMetricList()) {
|
||||
}
|
||||
|
||||
if(!CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())){
|
||||
for (SchemaItem metricDesc : chatDefaultConfig.getMetrics()) {
|
||||
DataInfo dataInfo = new DataInfo();
|
||||
dataInfo.setName(metricDesc.getName());
|
||||
dataInfo.setBizName(metricDesc.getBizName());
|
||||
@@ -115,6 +126,7 @@ public class DomainEntityService {
|
||||
entityInfo.setMetrics(metrics);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entityInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.utils.ComponentFactory;
|
||||
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 java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -50,7 +51,6 @@ public class QueryServiceImpl implements QueryService {
|
||||
log.info("semanticParser processing:[{}]", semanticParser.getClass().getName());
|
||||
semanticParser.parse(queryCtx, chatCtx);
|
||||
}
|
||||
|
||||
if (queryCtx.getCandidateQueries().size() > 0) {
|
||||
log.info("pick before [{}]", queryCtx.getCandidateQueries().stream().collect(
|
||||
Collectors.toList()));
|
||||
|
||||
@@ -29,7 +29,7 @@ public class RecommendServiceImpl implements RecommendService {
|
||||
}
|
||||
|
||||
DomainSchemaResp domainSchemaDesc = semanticLayer.getDomainSchemaInfo(
|
||||
Long.valueOf(domainId));
|
||||
Long.valueOf(domainId), true);
|
||||
|
||||
List<RecommendResponse.Item> dimensions = domainSchemaDesc.getDimensions().stream().map(dimSchemaDesc -> {
|
||||
RecommendResponse.Item item = new RecommendResponse.Item();
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.tencent.supersonic.chat.application;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
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.request.QueryContextReq;
|
||||
import com.tencent.supersonic.chat.application.knowledge.NatureHelper;
|
||||
@@ -64,8 +66,7 @@ public class SearchServiceImpl implements SearchService {
|
||||
List<ItemDO> metricsDb = domainInfosDb.getMetrics();
|
||||
final Map<Integer, String> domainToName = domainInfosDb.getDomainToName();
|
||||
// 2.detect by segment
|
||||
List<Term> originals = HanlpHelper.getSegment().seg(queryText.toLowerCase()).stream()
|
||||
.collect(Collectors.toList());
|
||||
List<Term> originals = HanlpHelper.getTerms(queryText);
|
||||
Map<MatchText, List<MapResult>> regTextMap = searchMatchStrategy.match(queryText, originals,
|
||||
queryCtx.getDomainId());
|
||||
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()) {
|
||||
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());
|
||||
}
|
||||
@@ -146,7 +147,8 @@ public class SearchServiceImpl implements SearchService {
|
||||
boolean existMetricAndDimension,
|
||||
MatchText matchText,
|
||||
Map<String, String> natureToNameMap,
|
||||
Map.Entry<String, String> natureToNameEntry) {
|
||||
Map.Entry<String, String> natureToNameEntry,
|
||||
QueryFilter queryFilter) {
|
||||
String nature = natureToNameEntry.getKey();
|
||||
String wordName = natureToNameEntry.getValue();
|
||||
|
||||
@@ -158,6 +160,9 @@ public class SearchServiceImpl implements SearchService {
|
||||
}
|
||||
// If there are no metric/dimension, complete the metric information
|
||||
if (metricDomainCount <= 0 && !existMetricAndDimension) {
|
||||
if (filterByQueryFilter(matchText.getRegText(), queryFilter)) {
|
||||
return;
|
||||
}
|
||||
searchResults.add(
|
||||
new SearchResult(matchText.getRegText() + wordName, wordName, domainToName.get(domain), domain,
|
||||
schemaElementType));
|
||||
@@ -167,7 +172,6 @@ public class SearchServiceImpl implements SearchService {
|
||||
}
|
||||
List<String> metrics = filerMetricsByDomain(metricsDb, domain).stream().limit(metricSize).collect(
|
||||
Collectors.toList());
|
||||
;
|
||||
for (String metric : metrics) {
|
||||
String subRecommend = matchText.getRegText() + wordName + NatureType.SPACE + metric;
|
||||
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) {
|
||||
if (CollectionUtils.isEmpty(metricsDb)) {
|
||||
return Lists.newArrayList();
|
||||
|
||||
@@ -31,8 +31,7 @@ public class DatabaseSchemaMapper implements SchemaMapper {
|
||||
|
||||
log.debug("before db mapper,mapInfo:{}", queryContext.getMapInfo());
|
||||
|
||||
List<Term> terms = HanlpHelper.getSegment().seg(queryContext.getQueryText().toLowerCase()).stream()
|
||||
.collect(Collectors.toList());
|
||||
List<Term> terms = HanlpHelper.getTerms(queryContext.getQueryText());
|
||||
|
||||
WordNatureService wordNatureService = ContextUtils.getBean(WordNatureService.class);
|
||||
|
||||
|
||||
@@ -30,8 +30,7 @@ public class HanlpSchemaMapper implements SchemaMapper {
|
||||
@Override
|
||||
public void map(QueryContextReq queryContext) {
|
||||
|
||||
List<Term> terms = HanlpHelper.getSegment().seg(queryContext.getQueryText().toLowerCase()).stream()
|
||||
.collect(Collectors.toList());
|
||||
List<Term> terms = HanlpHelper.getTerms(queryContext.getQueryText());
|
||||
|
||||
terms.forEach(
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void convertTermsToSchemaMapInfo(List<MapResult> mapResults, SchemaMapInfo schemaMap, List<Term> terms) {
|
||||
if (CollectionUtils.isEmpty(mapResults)) {
|
||||
return;
|
||||
|
||||
@@ -4,9 +4,12 @@ import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.chat.api.component.SchemaMapper;
|
||||
import com.tencent.supersonic.chat.api.pojo.*;
|
||||
import com.tencent.supersonic.chat.api.request.QueryContextReq;
|
||||
import com.tencent.supersonic.common.constant.Constants;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@@ -25,6 +28,7 @@ public class QueryFilterMapper implements SchemaMapper {
|
||||
QueryFilter queryFilter = queryContext.getQueryFilter();
|
||||
SchemaMapInfo schemaMapInfo = queryContext.getMapInfo();
|
||||
List<SchemaElementMatch> schemaElementMatches = schemaMapInfo.getMatchedElements(domainId);
|
||||
clearOtherSchemaElementMatch(domainId, schemaMapInfo);
|
||||
convertFilterToSchemaMapInfo(queryFilter.getFilters(), schemaElementMatches);
|
||||
}
|
||||
|
||||
@@ -33,6 +37,7 @@ public class QueryFilterMapper implements SchemaMapper {
|
||||
if (CollectionUtils.isEmpty(schemaElementMatches)) {
|
||||
schemaElementMatches = Lists.newArrayList();
|
||||
}
|
||||
List<String> words = schemaElementMatches.stream().map(SchemaElementMatch::getWord).collect(Collectors.toList());
|
||||
for (Filter filter : filters) {
|
||||
SchemaElementMatch schemaElementMatch = SchemaElementMatch.builder()
|
||||
.elementType(SchemaElementType.VALUE)
|
||||
@@ -40,11 +45,22 @@ public class QueryFilterMapper implements SchemaMapper {
|
||||
.frequency(FREQUENCY)
|
||||
.word(String.valueOf(filter.getValue()))
|
||||
.similarity(SIMILARITY)
|
||||
.detectWord(filter.getName())
|
||||
.detectWord(Constants.EMPTY)
|
||||
.build();
|
||||
if (words.contains(schemaElementMatch.getWord())) {
|
||||
continue;
|
||||
}
|
||||
schemaElementMatches.add(schemaElementMatch);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.SemanticParser;
|
||||
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.*;
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
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.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.config.ChatConfigRichInfo;
|
||||
import com.tencent.supersonic.chat.domain.utils.*;
|
||||
import com.tencent.supersonic.common.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.domain.service.ConfigService;
|
||||
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 java.util.*;
|
||||
import java.util.function.Function;
|
||||
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 org.springframework.util.CollectionUtils;
|
||||
|
||||
@@ -37,10 +41,15 @@ public class DomainSemanticParser implements SemanticParser {
|
||||
// iterate all schemaElementMatches to resolve semantic query
|
||||
for (Integer domainId : mapInfo.getMatchedDomains()) {
|
||||
List<SchemaElementMatch> elementMatches = mapInfo.getMatchedElements(domainId);
|
||||
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = resolveQuery(elementMatches, queryContext);
|
||||
for (Map.Entry<RuleSemanticQuery, List<SchemaElementMatch>> match : queryMatches.entrySet()) {
|
||||
List<RuleSemanticQuery> queries = resolveQuery(elementMatches, queryContext);
|
||||
for (RuleSemanticQuery query : queries) {
|
||||
|
||||
if (useBlackItem(query, domainId)) {
|
||||
log.info("useBlackItem, skip query:{}", query);
|
||||
continue;
|
||||
}
|
||||
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());
|
||||
if (mapInfo.getMatchedDomains().contains(chatDomainId)) {
|
||||
List<SchemaElementMatch> elementMatches = mapInfo.getMatchedElements(chatDomainId);
|
||||
detectionContext(chatContext);
|
||||
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = tryParseByContext(elementMatches,
|
||||
chatContext, queryContext);
|
||||
for (Map.Entry<RuleSemanticQuery, List<SchemaElementMatch>> match : queryMatches.entrySet()) {
|
||||
|
||||
List<RuleSemanticQuery> queries = tryParseByContext(elementMatches, chatContext, queryContext);
|
||||
for (RuleSemanticQuery query : queries) {
|
||||
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,
|
||||
Long domainId, String domainName,
|
||||
RuleSemanticQuery semanticQuery, List<SchemaElementMatch> elementMatches) {
|
||||
Long domainId, String domainName, RuleSemanticQuery semanticQuery) {
|
||||
if (semanticQuery != null) {
|
||||
fillParseInfo(semanticQuery, domainId, domainName, elementMatches);
|
||||
// inherit from context
|
||||
DefaultMetricUtils defaultMetricUtils = ContextUtils.getBean(DefaultMetricUtils.class);
|
||||
defaultMetricUtils.fillParseInfo(semanticQuery, domainId, domainName);
|
||||
inheritContext(semanticQuery, chatContext);
|
||||
// default metric, date, dimension
|
||||
injectDefaultMetric(semanticQuery, queryContext, chatContext);
|
||||
defaultMetricUtils.fillDefaultMetric(semanticQuery.getParseInfo(), queryContext, chatContext);
|
||||
queryContext.getCandidateQueries().add(semanticQuery);
|
||||
}
|
||||
}
|
||||
@@ -84,37 +161,14 @@ 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
|
||||
*
|
||||
* @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
|
||||
* try to add ChatContext to SchemaMatch and look if match QueryMode
|
||||
*
|
||||
* @param elementMatches
|
||||
* @param chatCtx
|
||||
* @return
|
||||
*/
|
||||
private Map<RuleSemanticQuery, List<SchemaElementMatch>> tryParseByContext(List<SchemaElementMatch> elementMatches,
|
||||
private List<RuleSemanticQuery> tryParseByContext(List<SchemaElementMatch> elementMatches,
|
||||
ChatContext chatCtx, QueryContextReq queryCtx) {
|
||||
if (chatCtx.getParseInfo() != null && chatCtx.getParseInfo().getEntity() > 0) {
|
||||
Long entityCount = elementMatches.stream().filter(i -> SchemaElementType.ENTITY.equals(i.getElementType()))
|
||||
@@ -125,15 +179,14 @@ public class DomainSemanticParser implements SemanticParser {
|
||||
// try entity parse
|
||||
SchemaElementMatch entityElementMatch = SchemaElementMatch.builder()
|
||||
.elementType(SchemaElementType.ENTITY).build();
|
||||
List<SchemaElementMatch> newSchemaElementMatch = new ArrayList<>();
|
||||
List<SchemaElementMatch> newSchemaMatches = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(elementMatches)) {
|
||||
newSchemaElementMatch.addAll(elementMatches);
|
||||
newSchemaMatches.addAll(elementMatches);
|
||||
}
|
||||
newSchemaElementMatch.add(entityElementMatch);
|
||||
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = doParseByContext(newSchemaElementMatch,
|
||||
chatCtx, queryCtx);
|
||||
if (queryMatches.size() > 0) {
|
||||
return queryMatches;
|
||||
newSchemaMatches.add(entityElementMatch);
|
||||
List<RuleSemanticQuery> queries = doParseByContext(newSchemaMatches, chatCtx, queryCtx);
|
||||
if (queries.size() > 0) {
|
||||
return queries;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,8 +194,8 @@ public class DomainSemanticParser implements SemanticParser {
|
||||
}
|
||||
|
||||
|
||||
private Map<RuleSemanticQuery, List<SchemaElementMatch>> doParseByContext(List<SchemaElementMatch> elementMatches,
|
||||
ChatContext chatCtx, QueryContextReq queryCtx) {
|
||||
private List<RuleSemanticQuery> doParseByContext(List<SchemaElementMatch> elementMatches,
|
||||
ChatContext chatCtx, QueryContextReq queryContext) {
|
||||
SemanticParseInfo contextSemanticParse = chatCtx.getParseInfo();
|
||||
if (contextSemanticParse != null) {
|
||||
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.DIMENSION)));
|
||||
|
||||
for (List<SchemaElementType> schemaElementTypes : trySchemaElementTypes) {
|
||||
for (List<SchemaElementType> schemaTypes : trySchemaElementTypes) {
|
||||
newElementMatches.clear();
|
||||
if (!CollectionUtils.isEmpty(elementMatches)) {
|
||||
newElementMatches.addAll(elementMatches);
|
||||
}
|
||||
ContextHelper.mergeContextSchemaElementMatch(newElementMatches, elementMatches, schemaElementTypes,
|
||||
ContextHelper.mergeContextSchemaElementMatch(newElementMatches, elementMatches, schemaTypes,
|
||||
contextSemanticParse);
|
||||
Map<RuleSemanticQuery, List<SchemaElementMatch>> queryMatches = resolveQuery(newElementMatches,
|
||||
queryCtx);
|
||||
if (queryMatches.size() > 0) {
|
||||
return queryMatches;
|
||||
List<RuleSemanticQuery> queries = resolveQuery(newElementMatches, queryContext);
|
||||
if (queries.size() > 0) {
|
||||
return queries;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new HashMap<>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private Map<RuleSemanticQuery, List<SchemaElementMatch>> resolveQuery(List<SchemaElementMatch> elementMatches,
|
||||
QueryContextReq queryCtx) {
|
||||
Map<RuleSemanticQuery, List<SchemaElementMatch>> matchMap = new HashMap<>();
|
||||
|
||||
private List<RuleSemanticQuery> resolveQuery(List<SchemaElementMatch> candidateElementMatches,
|
||||
QueryContextReq queryContext) {
|
||||
List<RuleSemanticQuery> matchedQueries = new ArrayList<>();
|
||||
for (RuleSemanticQuery semanticQuery : RuleSemanticQueryManager.getSemanticQueries()) {
|
||||
List<SchemaElementMatch> matches = semanticQuery.match(elementMatches, queryCtx);
|
||||
List<SchemaElementMatch> matches = semanticQuery.match(candidateElementMatches, queryContext);
|
||||
|
||||
if (matches.size() > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchedQueries;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.tencent.supersonic.chat.domain.utils.SemanticSatisfactionChecker;
|
||||
import com.tencent.supersonic.common.nlp.ItemDO;
|
||||
import com.tencent.supersonic.common.util.context.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.json.JsonUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +29,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
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.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.http.HttpEntity;
|
||||
@@ -40,13 +42,18 @@ import org.springframework.web.client.RestTemplate;
|
||||
@Slf4j
|
||||
public class LLMSemanticParser implements SemanticParser {
|
||||
|
||||
private DslToSemanticInfo dslToSemanticInfo = new DslToSemanticInfo();
|
||||
|
||||
@Override
|
||||
public void parse(QueryContextReq queryContext, ChatContext chatCtx) {
|
||||
String queryText = queryContext.getQueryText();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
try {
|
||||
Integer domainId = getDomainId(queryContext, chatCtx);
|
||||
LLMResp llmResp = requestLLM(queryContext, domainId);
|
||||
if (Objects.isNull(llmResp)) {
|
||||
@@ -54,23 +61,32 @@ public class LLMSemanticParser implements SemanticParser {
|
||||
}
|
||||
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);
|
||||
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;
|
||||
} catch (Exception e) {
|
||||
log.error("llm parse error , skip the parser. error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String convertToSql(LLMResp llmResp, SemanticParseInfo parseInfo) {
|
||||
return DslToSemanticInfo.convert(parseInfo, llmResp);
|
||||
protected String convertToSql(LLMResp llmResp, SemanticParseInfo parseInfo, Integer domainId)
|
||||
throws SqlParseException {
|
||||
return dslToSemanticInfo.convert(parseInfo, llmResp, domainId);
|
||||
}
|
||||
|
||||
protected LLMResp requestLLM(QueryContextReq queryContext, Integer domainId) {
|
||||
try {
|
||||
final LLMConfig llmConfig = ContextUtils.getBean(LLMConfig.class);
|
||||
|
||||
if (StringUtils.isEmpty(llmConfig.getUrl())) {
|
||||
log.warn("llmConfig url is null, skip llm parser");
|
||||
return null;
|
||||
}
|
||||
|
||||
DomainInfos domainInfos = ContextUtils.getBean(WordNatureService.class).getCache().getUnchecked("");
|
||||
|
||||
Map<Integer, String> domainIdToName = domainInfos.getDomains().stream()
|
||||
@@ -86,7 +102,7 @@ public class LLMSemanticParser implements SemanticParser {
|
||||
|
||||
List<SchemaElementMatch> matchedElements = queryContext.getMapInfo().getMatchedElements(domainId);
|
||||
|
||||
List<String> fieldNameList = matchedElements.stream()
|
||||
Set<String> fieldNameList = matchedElements.stream()
|
||||
.filter(schemaElementMatch ->
|
||||
SchemaElementType.METRIC.equals(schemaElementMatch.getElementType()) ||
|
||||
SchemaElementType.DIMENSION.equals(schemaElementMatch.getElementType()) ||
|
||||
@@ -98,14 +114,14 @@ public class LLMSemanticParser implements SemanticParser {
|
||||
return itemIdToName.get(schemaElementMatch.getElementID());
|
||||
})
|
||||
.filter(name -> StringUtils.isNotEmpty(name) && !name.contains("%"))
|
||||
.collect(Collectors.toList());
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
LLMSchema llmSchema = new LLMSchema();
|
||||
llmSchema.setDomainName(domainName);
|
||||
llmSchema.setFieldNameList(fieldNameList);
|
||||
llmSchema.setFieldNameList(new ArrayList<>(fieldNameList));
|
||||
llmReq.setSchema(llmSchema);
|
||||
|
||||
log.info("domainId:{},llmReq:{}", domainId, llmReq);
|
||||
log.info("requestLLM request, domainId:{},llmReq:{}", domainId, llmReq);
|
||||
String questUrl = llmConfig.getUrl() + llmConfig.getQueryToSqlPath();
|
||||
|
||||
RestTemplate restTemplate = ContextUtils.getBean(RestTemplate.class);
|
||||
@@ -114,16 +130,12 @@ public class LLMSemanticParser implements SemanticParser {
|
||||
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);
|
||||
log.info("requestLLM response, questUrl:{} \n entity:{} \n body:{}", questUrl, entity,
|
||||
responseEntity.getBody());
|
||||
return responseEntity.getBody();
|
||||
} catch (Exception e) {
|
||||
log.error("requestLLM error", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Integer getDomainId(QueryContextReq queryContext, ChatContext chatCtx) {
|
||||
|
||||
@@ -66,19 +66,18 @@ public class TimeSemanticParser implements SemanticParser {
|
||||
DateConf info = new DateConf();
|
||||
String zhPeriod = m.group("zhPeriod");
|
||||
int days;
|
||||
info.setPeriod(Constants.DAY);
|
||||
switch (zhPeriod) {
|
||||
case "周":
|
||||
days = 7;
|
||||
//info.setPeriod(Constants.WEEK);
|
||||
info.setPeriod(Constants.WEEK);
|
||||
break;
|
||||
case "月":
|
||||
days = 30;
|
||||
//info.setPeriod(Constants.MONTH);
|
||||
info.setPeriod(Constants.MONTH);
|
||||
break;
|
||||
case "年":
|
||||
days = 365;
|
||||
//info.setPeriod(Constants.YEAR);
|
||||
info.setPeriod(Constants.YEAR);
|
||||
break;
|
||||
default:
|
||||
days = 1;
|
||||
@@ -92,7 +91,7 @@ public class TimeSemanticParser implements SemanticParser {
|
||||
}
|
||||
info.setText(text);
|
||||
info.setStartDate(LocalDate.now().minusDays(days).toString());
|
||||
info.setUnit(days);
|
||||
info.setUnit(num);
|
||||
//queryContext.getParseInfo().setDateInfo(info);
|
||||
for (SemanticQuery query : queryContext.getCandidateQueries()) {
|
||||
if (query instanceof MetricSemanticQuery) {
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
package com.tencent.supersonic.chat.application.query;
|
||||
|
||||
import static com.tencent.supersonic.chat.api.pojo.SchemaElementType.VALUE;
|
||||
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.api.pojo.SchemaElementType.*;
|
||||
import static com.tencent.supersonic.chat.application.query.QueryMatchOption.RequireNumberType.*;
|
||||
import static com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption.*;
|
||||
import static com.tencent.supersonic.common.constant.Constants.DAY;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
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.service.ConfigService;
|
||||
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.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.Order;
|
||||
import com.tencent.supersonic.common.pojo.SchemaItem;
|
||||
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.MetricSchemaResp;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -34,11 +36,14 @@ public class EntityListFilter extends EntitySemanticQuery {
|
||||
public static String QUERY_MODE = "ENTITY_LIST_FILTER";
|
||||
private static Long entityListLimit = 200L;
|
||||
|
||||
|
||||
public EntityListFilter() {
|
||||
super();
|
||||
queryMatcher.addOption(VALUE, REQUIRED, AT_LEAST, 1);
|
||||
queryMatcher.addOption(VALUE, REQUIRED, AT_LEAST, 1)
|
||||
.addOption(ENTITY, REQUIRED, AT_LEAST, 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getQueryMode() {
|
||||
return QUERY_MODE;
|
||||
@@ -67,33 +72,32 @@ public class EntityListFilter extends EntitySemanticQuery {
|
||||
|
||||
private void addEntityDetailAndOrderByMetric(SemanticParseInfo semanticParseInfo) {
|
||||
if (semanticParseInfo.getDomainId() > 0L) {
|
||||
DefaultSemanticInternalUtils defaultSemanticUtils = ContextUtils.getBean(
|
||||
DefaultSemanticInternalUtils.class);
|
||||
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(
|
||||
ConfigService configService = ContextUtils.getBean(ConfigService.class);
|
||||
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(
|
||||
semanticParseInfo.getDomainId());
|
||||
if (chaConfigRichDesc != null) {
|
||||
if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null
|
||||
&& chaConfigRichDesc.getChatDetailRichConfig().getEntity() != null) {
|
||||
// SemanticParseInfo semanticParseInfo = queryContext.getParseInfo();
|
||||
// EntityRichInfo entity = chaConfigRichDesc.getChatDetailRichConfig().getEntity();
|
||||
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();
|
||||
if (chaConfigRichDesc.getEntity() != null
|
||||
&& chaConfigRichDesc.getEntity().getEntityInternalDetailDesc() != null) {
|
||||
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getMetricList().stream()
|
||||
.forEach((m) -> metrics.add(this.getMetric(m)));
|
||||
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getDimensionList().stream()
|
||||
.filter((m) -> !primaryDimensions.contains(m.getBizName()))
|
||||
.forEach((m) -> dimensions.add(this.getDimension(m)));
|
||||
Set<Order> orders = new LinkedHashSet();
|
||||
ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig();
|
||||
if (chatDefaultConfig != null) {
|
||||
chatDefaultConfig.getMetrics().stream()
|
||||
.forEach(metric -> {
|
||||
metrics.add(metric);
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
@@ -102,35 +106,18 @@ public class EntityListFilter extends EntitySemanticQuery {
|
||||
|
||||
private Set<String> addPrimaryDimension(EntityRichInfo entity, Set<SchemaItem> dimensions) {
|
||||
Set<String> primaryDimensions = new HashSet();
|
||||
if (!Objects.isNull(entity) && !CollectionUtils.isEmpty(entity.getEntityIds())) {
|
||||
entity.getEntityIds().stream().forEach((dimSchemaDesc) -> {
|
||||
DimSchemaResp dimItem = entity.getDimItem();
|
||||
if (Objects.nonNull(entity) && Objects.nonNull(dimItem)) {
|
||||
SchemaItem dimension = new SchemaItem();
|
||||
BeanUtils.copyProperties(dimSchemaDesc, dimension);
|
||||
BeanUtils.copyProperties(dimItem, dimension);
|
||||
dimensions.add(dimension);
|
||||
primaryDimensions.add(dimSchemaDesc.getBizName());
|
||||
});
|
||||
primaryDimensions.add(dimItem.getBizName());
|
||||
return primaryDimensions;
|
||||
} else {
|
||||
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) {
|
||||
if (Objects.nonNull(semanticParseInfo)) {
|
||||
semanticParseInfo.setNativeQuery(isNativeQuery);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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.domain.pojo.chat.SchemaElementOption.REQUIRED;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.tencent.supersonic.chat.domain.utils.ContextHelper;
|
||||
import com.tencent.supersonic.common.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -95,7 +96,7 @@ public class MetricCompare extends MetricSemanticQuery {
|
||||
if (toAdd.isPresent()) {
|
||||
if (FilterOperatorEnum.EQUALS.equals(toAdd.get().getOperator()) || FilterOperatorEnum.IN.equals(
|
||||
toAdd.get().getOperator())) {
|
||||
List<Object> vals = new ArrayList<>();
|
||||
Set<Object> vals = new HashSet<>();
|
||||
if (toAdd.get().getOperator().equals(FilterOperatorEnum.IN)) {
|
||||
vals.addAll((List<Object>) (toAdd.get().getValue()));
|
||||
} else {
|
||||
@@ -106,7 +107,7 @@ public class MetricCompare extends MetricSemanticQuery {
|
||||
} else {
|
||||
vals.add(filter.getValue());
|
||||
}
|
||||
toAdd.get().setValue(vals);
|
||||
toAdd.get().setValue(new ArrayList<>(vals));
|
||||
toAdd.get().setOperator(FilterOperatorEnum.IN);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -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.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.chat.SchemaElementOption;
|
||||
import com.tencent.supersonic.common.enums.AggregateTypeEnum;
|
||||
|
||||
@@ -12,10 +11,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.ToString;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
package com.tencent.supersonic.chat.application.query;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
@@ -24,7 +25,6 @@ import java.util.*;
|
||||
public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
|
||||
|
||||
protected SemanticParseInfo parseInfo = new SemanticParseInfo();
|
||||
protected List<SchemaElementMatch> schemaElementMatches = new ArrayList<>();
|
||||
protected QueryMatcher queryMatcher = new QueryMatcher();
|
||||
protected SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
|
||||
@@ -32,7 +32,8 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -57,6 +58,7 @@ public abstract class RuleSemanticQuery implements SemanticQuery, Serializable {
|
||||
QueryResultWithSchemaResp queryResult = semanticLayer.queryByStruct(
|
||||
SchemaInfoConverter.convertTo(parseInfo), user);
|
||||
|
||||
|
||||
if (queryResult != null) {
|
||||
queryResponse.setQueryAuthorization(queryResult.getQueryAuthorization());
|
||||
}
|
||||
|
||||
@@ -16,8 +16,4 @@ public class LLMConfig {
|
||||
@Value("${query2sql.path:query2sql}")
|
||||
private String queryToSqlPath;
|
||||
|
||||
|
||||
@Value("${query2sql.endpoint:}")
|
||||
private String endpoint;
|
||||
|
||||
}
|
||||
|
||||
@@ -15,29 +15,11 @@ public class ChatConfigDO {
|
||||
private Long id;
|
||||
|
||||
private Long domainId;
|
||||
/**
|
||||
* default metrics information about the domain
|
||||
*/
|
||||
private String defaultMetrics;
|
||||
|
||||
/**
|
||||
* invisible dimensions/metrics
|
||||
*/
|
||||
private String visibility;
|
||||
private String chatDetailConfig;
|
||||
|
||||
/**
|
||||
* the entity info about the domain
|
||||
*/
|
||||
private String entity;
|
||||
private String chatAggConfig;
|
||||
|
||||
/**
|
||||
* information about dictionary about the domain
|
||||
*/
|
||||
private String knowledgeInfo;
|
||||
|
||||
/**
|
||||
* available status
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -16,25 +16,16 @@ public class ChatConfig {
|
||||
private Long id;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* information about dictionary about the domain
|
||||
*/
|
||||
private List<KnowledgeInfo> knowledgeInfos;
|
||||
private ChatAggConfig chatAggConfig;
|
||||
|
||||
/**
|
||||
* available status
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class ChatConfigEditReq extends ChatConfigBase {
|
||||
public class ChatConfigEditReqReq extends ChatConfigBaseReq {
|
||||
|
||||
private Long id;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -1,41 +1,29 @@
|
||||
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
|
||||
*/
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class ChatConfigBase {
|
||||
|
||||
private Long domainId;
|
||||
/**
|
||||
* default metrics information about the domain
|
||||
*/
|
||||
private List<DefaultMetricInfo> defaultMetrics;
|
||||
public class ChatDetailConfig {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
private KnowledgeAdvancedConfig globalKnowledgeConfig;
|
||||
|
||||
private ChatDefaultConfig chatDefaultConfig;
|
||||
|
||||
/**
|
||||
* available status
|
||||
* the entity info about the domain
|
||||
*/
|
||||
private StatusEnum status;
|
||||
private Entity entity;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
@@ -3,11 +3,13 @@ package com.tencent.supersonic.chat.domain.pojo.config;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
public class Dim4Dict {
|
||||
|
||||
private Long dimId;
|
||||
|
||||
@@ -18,16 +18,12 @@ public class Entity {
|
||||
/**
|
||||
* uniquely identifies an entity
|
||||
*/
|
||||
private List<Long> entityIds;
|
||||
private Long entityId;
|
||||
|
||||
/**
|
||||
* entity name list
|
||||
*/
|
||||
private List<String> names;
|
||||
|
||||
/**
|
||||
* query entity default information
|
||||
*/
|
||||
private EntityDetailData detailData;
|
||||
|
||||
}
|
||||
@@ -7,14 +7,14 @@ import lombok.Data;
|
||||
@Data
|
||||
public class EntityRichInfo {
|
||||
|
||||
private Long domainId;
|
||||
private String domainName;
|
||||
private String domainBizName;
|
||||
// private Long domainId;
|
||||
// private String domainName;
|
||||
// private String domainBizName;
|
||||
|
||||
/**
|
||||
* entity alias
|
||||
*/
|
||||
private List<String> names;
|
||||
|
||||
private List<DimSchemaResp> entityIds;
|
||||
|
||||
private EntityInternalDetail entityInternalDetailDesc;
|
||||
|
||||
private DimSchemaResp dimItem;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.tencent.supersonic.chat.domain.pojo.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
@@ -12,10 +13,10 @@ public class ItemVisibility {
|
||||
/**
|
||||
* invisible dimensions
|
||||
*/
|
||||
private List<Long> blackDimIdList;
|
||||
private List<Long> blackDimIdList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* invisible metrics
|
||||
*/
|
||||
private List<Long> blackMetricIdList;
|
||||
private List<Long> blackMetricIdList = new ArrayList<>();
|
||||
}
|
||||
@@ -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<>();
|
||||
}
|
||||
@@ -27,9 +27,12 @@ public class KnowledgeInfo {
|
||||
@NotNull
|
||||
private TypeEnums type = TypeEnums.DIMENSION;
|
||||
|
||||
private List<String> blackList;
|
||||
private List<String> whiteList;
|
||||
private List<String> ruleList;
|
||||
private Boolean isDictInfo;
|
||||
private Boolean searchEnable = false;
|
||||
|
||||
/**
|
||||
* advanced knowledge config for single item
|
||||
*/
|
||||
private KnowledgeAdvancedConfig knowledgeAdvancedConfig;
|
||||
|
||||
|
||||
}
|
||||
@@ -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.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public interface ChatConfigRepository {
|
||||
|
||||
Long updateConfig(ChatConfig chaConfig);
|
||||
|
||||
List<ChatConfigInfo> getChatConfig(ChatConfigFilter filter);
|
||||
List<ChatConfigResp> getChatConfig(ChatConfigFilter filter);
|
||||
|
||||
ChatConfigInfo getConfigByDomainId(Long domainId);
|
||||
ChatConfigResp getConfigByDomainId(Long domainId);
|
||||
}
|
||||
|
||||
@@ -2,22 +2,25 @@ package com.tencent.supersonic.chat.domain.service;
|
||||
|
||||
|
||||
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.ChatConfigEditReq;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBaseReq;
|
||||
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.ChatConfigInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -3,20 +3,11 @@ package com.tencent.supersonic.chat.domain.utils;
|
||||
import static com.tencent.supersonic.common.constant.Constants.ADMIN_LOWER;
|
||||
|
||||
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.DomainSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
|
||||
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.util.RecordInfo;
|
||||
import com.tencent.supersonic.common.util.json.JsonUtil;
|
||||
@@ -39,31 +30,28 @@ import org.springframework.util.CollectionUtils;
|
||||
@Slf4j
|
||||
public class ChatConfigUtils {
|
||||
|
||||
public ChatConfig newChatConfig(ChatConfigBase extendBaseCmd, User user) {
|
||||
ChatConfig chaConfig = new ChatConfig();
|
||||
|
||||
BeanUtils.copyProperties(extendBaseCmd, chaConfig);
|
||||
|
||||
public ChatConfig newChatConfig(ChatConfigBaseReq extendBaseCmd, User user) {
|
||||
ChatConfig chatConfig = new ChatConfig();
|
||||
BeanUtils.copyProperties(extendBaseCmd, chatConfig);
|
||||
RecordInfo recordInfo = new RecordInfo();
|
||||
String creator = (Objects.isNull(user) || Strings.isEmpty(user.getName())) ? ADMIN_LOWER : user.getName();
|
||||
recordInfo.createdBy(creator);
|
||||
chaConfig.setRecordInfo(recordInfo);
|
||||
chaConfig.setStatus(StatusEnum.ONLINE);
|
||||
return chaConfig;
|
||||
chatConfig.setRecordInfo(recordInfo);
|
||||
chatConfig.setStatus(StatusEnum.ONLINE);
|
||||
return chatConfig;
|
||||
}
|
||||
|
||||
|
||||
public ChatConfig editChaConfig(ChatConfigEditReq extendEditCmd, User facadeUser) {
|
||||
ChatConfig chaConfig = new ChatConfig();
|
||||
|
||||
BeanUtils.copyProperties(extendEditCmd, chaConfig);
|
||||
public ChatConfig editChatConfig(ChatConfigEditReqReq extendEditCmd, User facadeUser) {
|
||||
ChatConfig chatConfig = new ChatConfig();
|
||||
|
||||
BeanUtils.copyProperties(extendEditCmd, chatConfig);
|
||||
RecordInfo recordInfo = new RecordInfo();
|
||||
String user = (Objects.isNull(facadeUser) || Strings.isEmpty(facadeUser.getName()))
|
||||
? ADMIN_LOWER : facadeUser.getName();
|
||||
recordInfo.updatedBy(user);
|
||||
chaConfig.setRecordInfo(recordInfo);
|
||||
return chaConfig;
|
||||
chatConfig.setRecordInfo(recordInfo);
|
||||
return chatConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,45 +114,76 @@ public class ChatConfigUtils {
|
||||
return new ArrayList<>(metricIdAndDescPair.keySet());
|
||||
}
|
||||
|
||||
public ChatConfigDO chatConfig2DO(ChatConfig chaConfig) {
|
||||
ChatConfigDO chaConfigDO = new ChatConfigDO();
|
||||
BeanUtils.copyProperties(chaConfig, chaConfigDO);
|
||||
public ChatConfigDO chatConfig2DO(ChatConfig chatConfig) {
|
||||
ChatConfigDO chatConfigDO = new ChatConfigDO();
|
||||
BeanUtils.copyProperties(chatConfig, chatConfigDO);
|
||||
|
||||
chaConfigDO.setDefaultMetrics(JsonUtil.toString(chaConfig.getDefaultMetrics()));
|
||||
chaConfigDO.setVisibility(JsonUtil.toString(chaConfig.getVisibility()));
|
||||
chaConfigDO.setEntity(JsonUtil.toString(chaConfig.getEntity()));
|
||||
chaConfigDO.setKnowledgeInfo(JsonUtil.toString(chaConfig.getKnowledgeInfos()));
|
||||
chatConfigDO.setChatAggConfig(JsonUtil.toString(chatConfig.getChatAggConfig()));
|
||||
chatConfigDO.setChatDetailConfig(JsonUtil.toString(chatConfig.getChatDetailConfig()));
|
||||
|
||||
if (Objects.isNull(chaConfig.getStatus())) {
|
||||
chaConfigDO.setStatus(null);
|
||||
if (Objects.isNull(chatConfig.getStatus())) {
|
||||
chatConfigDO.setStatus(null);
|
||||
} else {
|
||||
chaConfigDO.setStatus(chaConfig.getStatus().getCode());
|
||||
chatConfigDO.setStatus(chatConfig.getStatus().getCode());
|
||||
}
|
||||
|
||||
chaConfigDO.setCreatedBy(chaConfig.getRecordInfo().getCreatedBy());
|
||||
chaConfigDO.setCreatedAt(chaConfig.getRecordInfo().getCreatedAt());
|
||||
chaConfigDO.setUpdatedBy(chaConfig.getRecordInfo().getUpdatedBy());
|
||||
chaConfigDO.setUpdatedAt(chaConfig.getRecordInfo().getUpdatedAt());
|
||||
chatConfigDO.setCreatedBy(chatConfig.getRecordInfo().getCreatedBy());
|
||||
chatConfigDO.setCreatedAt(chatConfig.getRecordInfo().getCreatedAt());
|
||||
chatConfigDO.setUpdatedBy(chatConfig.getRecordInfo().getUpdatedBy());
|
||||
chatConfigDO.setUpdatedAt(chatConfig.getRecordInfo().getUpdatedAt());
|
||||
|
||||
return chaConfigDO;
|
||||
return chatConfigDO;
|
||||
}
|
||||
|
||||
public ChatConfigInfo chatConfigDO2Descriptor(ChatConfigDO chaConfigDO) {
|
||||
ChatConfigInfo chaConfigDescriptor = new ChatConfigInfo();
|
||||
BeanUtils.copyProperties(chaConfigDO, chaConfigDescriptor);
|
||||
public ChatConfigResp chatConfigDO2Descriptor(Long domainId, ChatConfigDO chatConfigDO) {
|
||||
ChatConfigResp chatConfigDescriptor = new ChatConfigResp();
|
||||
|
||||
chaConfigDescriptor.setDefaultMetrics(
|
||||
JsonUtil.toList(chaConfigDO.getDefaultMetrics(), DefaultMetricInfo.class));
|
||||
chaConfigDescriptor.setVisibility(JsonUtil.toObject(chaConfigDO.getVisibility(), ItemVisibility.class));
|
||||
chaConfigDescriptor.setEntity(JsonUtil.toObject(chaConfigDO.getEntity(), Entity.class));
|
||||
chaConfigDescriptor.setKnowledgeInfos(JsonUtil.toList(chaConfigDO.getKnowledgeInfo(), KnowledgeInfo.class));
|
||||
chaConfigDescriptor.setStatusEnum(StatusEnum.of(chaConfigDO.getStatus()));
|
||||
if (Objects.isNull(chatConfigDO)) {
|
||||
// deal empty chatConfigDO
|
||||
return generateEmptyChatConfigResp(domainId);
|
||||
}
|
||||
|
||||
chaConfigDescriptor.setCreatedBy(chaConfigDO.getCreatedBy());
|
||||
chaConfigDescriptor.setCreatedAt(chaConfigDO.getCreatedAt());
|
||||
chaConfigDescriptor.setUpdatedBy(chaConfigDO.getUpdatedBy());
|
||||
chaConfigDescriptor.setUpdatedAt(chaConfigDO.getUpdatedAt());
|
||||
BeanUtils.copyProperties(chatConfigDO, chatConfigDescriptor);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
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.Filter;
|
||||
import com.tencent.supersonic.chat.api.pojo.QueryMatchInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
||||
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.common.pojo.SchemaItem;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.tencent.supersonic.semantic.api.core.response.DimSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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 {
|
||||
|
||||
@@ -137,17 +137,18 @@ public class ContextHelper {
|
||||
return difference;
|
||||
}
|
||||
|
||||
public static void setEntityId(Long dimensionId, String value, ChatConfigRichInfo chaConfigRichDesc,
|
||||
public static void setEntityId(Long dimensionId, String value, ChatConfigRichResp chaConfigRichDesc,
|
||||
SemanticParseInfo semanticParseInfo) {
|
||||
if (chaConfigRichDesc != null && chaConfigRichDesc.getEntity() != null) {
|
||||
Optional<DimSchemaResp> dimensionDesc = chaConfigRichDesc.getEntity().getEntityIds().stream()
|
||||
.filter(i -> i.getId().equals(dimensionId)).findFirst();
|
||||
if (dimensionDesc.isPresent() && StringUtils.isNumeric(value)) {
|
||||
if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null
|
||||
&& chaConfigRichDesc.getChatDetailRichConfig().getEntity() != null) {
|
||||
DimSchemaResp dimSchemaResp = chaConfigRichDesc.getChatDetailRichConfig().getEntity().getDimItem();
|
||||
if (Objects.nonNull(dimSchemaResp) && StringUtils.isNumeric(value)) {
|
||||
semanticParseInfo.setEntity(Long.valueOf(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean hasEntityId(ChatContext chatCtx) {
|
||||
if (chatCtx != null && chatCtx.getParseInfo() != null) {
|
||||
return chatCtx.getParseInfo().getEntity() > 0;
|
||||
@@ -198,9 +199,17 @@ public class ContextHelper {
|
||||
for (Filter chatFilter : contextSemanticParse.getDimensionFilters()) {
|
||||
if (!isInSchemaElementMatchList(elementMatches, SchemaElementType.VALUE,
|
||||
chatFilter.getValue().toString())) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if (chatFilter.getOperator().equals(FilterOperatorEnum.IN)) {
|
||||
values.addAll((List<String>) chatFilter.getValue());
|
||||
} else {
|
||||
values.add(chatFilter.getValue().toString());
|
||||
}
|
||||
for (String value : values) {
|
||||
toSchemaElementMatch.add(
|
||||
getSchemaElementMatchByContext(chatFilter.getElementID().intValue(),
|
||||
chatFilter.getValue().toString(), SchemaElementType.VALUE));
|
||||
value, SchemaElementType.VALUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,8 +233,7 @@ public class ContextHelper {
|
||||
return false;
|
||||
}
|
||||
Long num = elementMatches.stream()
|
||||
.filter(element -> element != null && element.getWord() != null && element.getWord()
|
||||
.equalsIgnoreCase(word) && element.getElementType().equals(schemaElementType)).count();
|
||||
.filter(element -> element != null && element.getElementType().equals(schemaElementType)).count();
|
||||
return num > 0;
|
||||
}
|
||||
|
||||
@@ -247,6 +255,7 @@ public class ContextHelper {
|
||||
.elementID(id)
|
||||
.elementType(schemaElementType)
|
||||
.word(word)
|
||||
.detectWord(word)
|
||||
.similarity(0.5)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -2,34 +2,33 @@ package com.tencent.supersonic.chat.domain.utils;
|
||||
|
||||
import static java.time.LocalDate.now;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.ChatContext;
|
||||
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.component.SemanticLayer;
|
||||
import com.tencent.supersonic.chat.api.component.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.*;
|
||||
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.query.EntityDetail;
|
||||
import com.tencent.supersonic.chat.application.query.EntityListFilter;
|
||||
import com.tencent.supersonic.chat.application.query.EntityListTopN;
|
||||
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.application.query.*;
|
||||
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.common.constant.Constants;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.SchemaItem;
|
||||
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.DomainSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.core.response.MetricSchemaResp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.tencent.supersonic.semantic.api.query.enums.FilterOperatorEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.util.CollectionUtils;
|
||||
|
||||
@@ -37,57 +36,74 @@ import org.springframework.util.CollectionUtils;
|
||||
@Component
|
||||
public class DefaultMetricUtils {
|
||||
|
||||
@Autowired
|
||||
private ConfigServiceImpl configService;
|
||||
|
||||
/**
|
||||
* supplementary default metric date dimension
|
||||
*/
|
||||
public void injectDefaultMetric(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext,
|
||||
public void fillDefaultMetric(SemanticParseInfo semanticParseInfo, QueryContextReq queryContext,
|
||||
ChatContext chatContext) {
|
||||
String queryMode = semanticParseInfo.getQueryMode();
|
||||
ChatConfigRichInfo chaConfigRichDesc = null;
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
if (!EntityListFilter.QUERY_MODE.equals(queryMode)) {
|
||||
boolean isFillThemeDefaultMetricLogic = false;
|
||||
boolean isAddEntityDetailDimensionMetric = false;
|
||||
// if (!EntityListFilter.QUERY_MODE.equals(queryMode)) {
|
||||
boolean isFillAggDefaultMetricLogic = false;
|
||||
boolean isFillDetailDimensionMetric = false;
|
||||
Integer domainId = queryContext.getDomainId().intValue();
|
||||
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)) {
|
||||
long metricCount = matchedElements.stream()
|
||||
.filter(schemaElementMatch -> schemaElementMatch.getElementType()
|
||||
.equals(SchemaElementType.METRIC)).count();
|
||||
|
||||
if (metricCount <= 0) {
|
||||
if (chatContext.getParseInfo() == null
|
||||
|| chatContext.getParseInfo().getMetrics() == null
|
||||
|| 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)) {
|
||||
isAddEntityDetailDimensionMetric = true;
|
||||
dealNativeQuery(semanticParseInfo, queryContext, true);
|
||||
if (Objects.nonNull(chaConfigRichDesc.getChatAggRichConfig())) {
|
||||
chatDefaultConfig = chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig();
|
||||
}
|
||||
|
||||
if (isFillThemeDefaultMetricLogic) {
|
||||
if (chaConfigRichDesc == null) {
|
||||
chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId());
|
||||
} else if (ruleSemanticQuery instanceof EntitySemanticQuery) {
|
||||
log.info("fillThemeDefaultMetricLogic for empty matchedElements ");
|
||||
isFillDetailDimensionMetric = true;
|
||||
dealNativeQuery(semanticParseInfo, queryContext, true);
|
||||
isDetailMode = true;
|
||||
if (Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig())) {
|
||||
chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig();
|
||||
}
|
||||
fillThemeDefaultMetricLogic(semanticParseInfo, chaConfigRichDesc, queryContext);
|
||||
}
|
||||
if (isAddEntityDetailDimensionMetric) {
|
||||
if (chaConfigRichDesc == null) {
|
||||
chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId());
|
||||
|
||||
|
||||
if (isFillAggDefaultMetricLogic) {
|
||||
fillDefaultMetricAggLogic(semanticParseInfo, chaConfigRichDesc, queryContext);
|
||||
}
|
||||
|
||||
if (isFillDetailDimensionMetric) {
|
||||
addEntityDetailDimensionMetric(semanticParseInfo, chaConfigRichDesc, queryContext, chatContext);
|
||||
}
|
||||
fillDateDomain(semanticParseInfo, chatContext, chaConfigRichDesc, queryContext);
|
||||
}
|
||||
|
||||
fillDateDomain(semanticParseInfo, chatContext, chaConfigRichDesc, chatDefaultConfig, isDetailMode);
|
||||
// }
|
||||
defaultQueryMode(semanticParseInfo, queryContext, chatContext);
|
||||
addEntityTopDimension(semanticParseInfo, chaConfigRichDesc);
|
||||
}
|
||||
@@ -102,22 +118,18 @@ public class DefaultMetricUtils {
|
||||
|
||||
public Set<String> addPrimaryDimension(EntityRichInfo entity, List<SchemaItem> dimensions) {
|
||||
Set<String> primaryDimensions = new HashSet<>();
|
||||
if (Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getEntityIds())) {
|
||||
if (Objects.isNull(entity) || Objects.isNull(entity.getDimItem())) {
|
||||
return primaryDimensions;
|
||||
}
|
||||
entity.getEntityIds().stream().forEach(dimSchemaDesc -> {
|
||||
DimSchemaResp dimItem = entity.getDimItem();
|
||||
SchemaItem dimension = new SchemaItem();
|
||||
//BeanUtils.copyProperties(dimSchemaDesc, dimension);
|
||||
dimension.setName(dimSchemaDesc.getName());
|
||||
dimension.setBizName(dimSchemaDesc.getBizName());
|
||||
dimension.setId(dimSchemaDesc.getId());
|
||||
BeanUtils.copyProperties(dimItem, dimension);
|
||||
dimensions.add(dimension);
|
||||
primaryDimensions.add(dimSchemaDesc.getBizName());
|
||||
});
|
||||
primaryDimensions.add(dimItem.getBizName());
|
||||
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()
|
||||
.isEmpty()) {
|
||||
return;
|
||||
@@ -127,37 +139,49 @@ public class DefaultMetricUtils {
|
||||
if (chaConfigRichDesc == null) {
|
||||
chaConfigRichDesc = getChatConfigRichInfo(domainId);
|
||||
}
|
||||
if (chaConfigRichDesc != null && chaConfigRichDesc.getEntity() != null) {
|
||||
if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null
|
||||
&& chaConfigRichDesc.getChatDetailRichConfig().getEntity() != null) {
|
||||
List<SchemaItem> dimensions = new ArrayList<>();
|
||||
addPrimaryDimension(chaConfigRichDesc.getEntity(), dimensions);
|
||||
addPrimaryDimension(chaConfigRichDesc.getChatDetailRichConfig().getEntity(), dimensions);
|
||||
semanticParseInfo.setDimensions(new HashSet<>(dimensions));
|
||||
semanticParseInfo.setLimit(1L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addEntityDetailDimensionMetric(SemanticParseInfo semanticParseInfo,
|
||||
ChatConfigRichInfo chaConfigRichDesc, QueryContextReq queryContext,
|
||||
public void addEntityDetailDimensionMetric(SemanticParseInfo semanticParseInfo, ChatConfigRichResp chaConfigRichDesc, QueryContextReq queryContext,
|
||||
ChatContext chatCtx) {
|
||||
if (semanticParseInfo.getDomainId() > 0) {
|
||||
Long domainId = semanticParseInfo.getDomainId();
|
||||
|
||||
if (chaConfigRichDesc != null) {
|
||||
if (chaConfigRichDesc.getEntity() == null
|
||||
|| chaConfigRichDesc.getEntity().getEntityInternalDetailDesc() == null) {
|
||||
if (chaConfigRichDesc != null && chaConfigRichDesc.getChatDetailRichConfig() != null) {
|
||||
if (chaConfigRichDesc.getChatDetailRichConfig().getEntity() == null
|
||||
|| chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<SchemaElementMatch> schemaElementMatches = queryContext.getMapInfo()
|
||||
.getMatchedElements(domainId.intValue());
|
||||
if (CollectionUtils.isEmpty(schemaElementMatches) || schemaElementMatches.stream()
|
||||
.filter(s -> SchemaElementType.DIMENSION.equals(s.getElementType())).count() <= 0) {
|
||||
if (CollectionUtils.isEmpty(schemaElementMatches)
|
||||
|| schemaElementMatches.stream().filter(s -> SchemaElementType.DIMENSION.equals(s.getElementType())).count() <= 0) {
|
||||
log.info("addEntityDetailDimensionMetric catch");
|
||||
if (CollectionUtils.isEmpty(semanticParseInfo.getDimensions())) {
|
||||
Set<SchemaItem> dimensions = new LinkedHashSet();
|
||||
chaConfigRichDesc.getEntity().getEntityInternalDetailDesc().getDimensionList().stream()
|
||||
.forEach(m -> dimensions.add(getDimension(m)));
|
||||
List<SchemaItem> dimensionsConfig = chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig().getDimensions();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
if (parseInfo == null || parseInfo.getDateInfo() == null) {
|
||||
@@ -232,16 +341,18 @@ public class DefaultMetricUtils {
|
||||
isUpdateTime = true;
|
||||
}
|
||||
if (isUpdateTime && parseInfo != null && parseInfo.getDomainId() > 0) {
|
||||
fillThemeDefaultTime(parseInfo.getDomainId(), chaConfigRichDesc, parseInfo);
|
||||
|
||||
fillThemeDefaultTime(chaConfigRichDesc, parseInfo, chatDefaultConfig, isDetailMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fillThemeDefaultMetricLogic(SemanticParseInfo semanticParseInfo, ChatConfigRichInfo chaConfigRichDesc,
|
||||
QueryContextReq queryContext) {
|
||||
public void fillDefaultMetricAggLogic(SemanticParseInfo semanticParseInfo, ChatConfigRichResp chaConfigRichDesc, QueryContextReq queryContext) {
|
||||
//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");
|
||||
return;
|
||||
}
|
||||
@@ -258,9 +369,9 @@ public class DefaultMetricUtils {
|
||||
.filter(e -> e.getElementType().equals(SchemaElementType.DIMENSION)).count();
|
||||
if (metricNum <= 0 && dimensionNum <= 0) {
|
||||
Set<SchemaItem> metrics = new LinkedHashSet();
|
||||
chaConfigRichDesc.getDefaultMetrics().stream().forEach(metric -> {
|
||||
chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig().getMetrics().stream().forEach(metric -> {
|
||||
SchemaItem metricTmp = new SchemaItem();
|
||||
metricTmp.setId(metric.getMetricId());
|
||||
metricTmp.setId(metric.getId());
|
||||
metricTmp.setBizName(metric.getBizName());
|
||||
metrics.add(metricTmp);
|
||||
});
|
||||
@@ -269,18 +380,17 @@ public class DefaultMetricUtils {
|
||||
|
||||
if (Objects.isNull(semanticParseInfo.getDateInfo()) || Objects.isNull(
|
||||
semanticParseInfo.getDateInfo().getDateMode())) {
|
||||
DefaultMetric defaultMetricInfo = chaConfigRichDesc.getDefaultMetrics().get(0);
|
||||
ChatDefaultRichConfig chatDefaultConfig = chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig();
|
||||
DateConf dateInfo = new DateConf();
|
||||
dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS);
|
||||
dateInfo.setUnit(defaultMetricInfo.getUnit());
|
||||
dateInfo.setPeriod(defaultMetricInfo.getPeriod());
|
||||
dateInfo.setUnit(chatDefaultConfig.getUnit());
|
||||
dateInfo.setPeriod(chatDefaultConfig.getPeriod());
|
||||
semanticParseInfo.setDateInfo(dateInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void fillThemeDefaultTime(Long domain, ChatConfigRichInfo chaConfigRichDesc,
|
||||
SemanticParseInfo semanticParseInfo) {
|
||||
public void fillThemeDefaultTime(ChatConfigRichResp chaConfigRichDesc, SemanticParseInfo semanticParseInfo, ChatDefaultRichConfig chatDefaultConfig, Boolean isDetailMode) {
|
||||
if (!Objects.isNull(semanticParseInfo.getDateInfo()) && !Objects.isNull(
|
||||
semanticParseInfo.getDateInfo().getDateMode())) {
|
||||
return;
|
||||
@@ -288,22 +398,26 @@ public class DefaultMetricUtils {
|
||||
if (chaConfigRichDesc == null) {
|
||||
chaConfigRichDesc = getChatConfigRichInfo(semanticParseInfo.getDomainId());
|
||||
}
|
||||
if (!Objects.isNull(chaConfigRichDesc) && !CollectionUtils.isEmpty(chaConfigRichDesc.getDefaultMetrics())) {
|
||||
DefaultMetric defaultMetricInfo = chaConfigRichDesc.getDefaultMetrics().get(0);
|
||||
if (!Objects.isNull(chaConfigRichDesc) && Objects.nonNull(chatDefaultConfig) && !CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())) {
|
||||
DateConf dateInfo = new DateConf();
|
||||
if (isDetailMode) {
|
||||
dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS);
|
||||
dateInfo.setUnit(defaultMetricInfo.getUnit());
|
||||
dateInfo.setStartDate(now().minusDays(defaultMetricInfo.getUnit()).toString());
|
||||
dateInfo.setEndDate(now().minusDays(1).toString());
|
||||
dateInfo.setPeriod(defaultMetricInfo.getPeriod());
|
||||
dateInfo.setUnit(1);
|
||||
dateInfo.setPeriod(Constants.DAY);
|
||||
} else {
|
||||
dateInfo.setDateMode(DateConf.DateMode.RECENT_UNITS);
|
||||
dateInfo.setUnit(chatDefaultConfig.getUnit());
|
||||
dateInfo.setPeriod(chatDefaultConfig.getPeriod());
|
||||
}
|
||||
|
||||
|
||||
semanticParseInfo.setDateInfo(dateInfo);
|
||||
log.info("fillThemeDefaultTime");
|
||||
}
|
||||
}
|
||||
|
||||
public ChatConfigRichInfo getChatConfigRichInfo(Long domain) {
|
||||
DefaultSemanticInternalUtils defaultSemanticUtils = ContextUtils.getBean(DefaultSemanticInternalUtils.class);
|
||||
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(domain);
|
||||
public ChatConfigRichResp getChatConfigRichInfo(Long domain) {
|
||||
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(domain);
|
||||
return chaConfigRichDesc;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,12 @@ import static com.tencent.supersonic.common.constant.Constants.DAY;
|
||||
import static com.tencent.supersonic.common.constant.Constants.UNDERLINE;
|
||||
|
||||
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.DomainSchemaResp;
|
||||
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.DimValue2DictCommand;
|
||||
|
||||
@@ -25,6 +23,8 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -32,13 +32,15 @@ import org.springframework.util.CollectionUtils;
|
||||
@Component
|
||||
public class DictMetaUtils {
|
||||
|
||||
private final DefaultSemanticInternalUtils defaultSemanticUtils;
|
||||
@Autowired
|
||||
private ConfigServiceImpl configService;
|
||||
|
||||
@Value("${model.internal.metric.suffix:internal_cnt}")
|
||||
private String internalMetricNameSuffix;
|
||||
private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
|
||||
public DictMetaUtils(DefaultSemanticInternalUtils defaultSemanticUtils) {
|
||||
this.defaultSemanticUtils = defaultSemanticUtils;
|
||||
public DictMetaUtils() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -129,38 +131,59 @@ public class DictMetaUtils {
|
||||
|
||||
private void fillDimValueDOList(List<DimValueDO> dimValueDOList, Long domainId,
|
||||
Map<Long, DimSchemaResp> dimIdAndDescPair) {
|
||||
ChatConfigRichInfo chaConfigRichDesc = defaultSemanticUtils.getChatConfigRichInfo(domainId);
|
||||
if (Objects.nonNull(chaConfigRichDesc)) {
|
||||
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(domainId);
|
||||
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();
|
||||
|
||||
fillKnowledgeDimValue(knowledgeDetailInfo, chatDefaultConfig, dimValueDOList, dimIdAndDescPair, domainId);
|
||||
fillKnowledgeDimValue(knowledgeAggInfo, chatDefaultConfig, dimValueDOList, dimIdAndDescPair, domainId);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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.getIsDictInfo()
|
||||
&& isVisibleDim(knowledgeInfo, chaConfigRichDesc.getVisibility()))
|
||||
.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 (CollectionUtils.isEmpty(defaultMetricDescList)) {
|
||||
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()));
|
||||
Dim4Dict dim4Dict = new Dim4Dict();
|
||||
dim4Dict.setDimId(knowledgeInfo.getItemId());
|
||||
dim4Dict.setBizName(bizName);
|
||||
if(Objects.nonNull(knowledgeInfo.getKnowledgeAdvancedConfig())){
|
||||
KnowledgeAdvancedConfig knowledgeAdvancedConfig = knowledgeInfo.getKnowledgeAdvancedConfig();
|
||||
BeanUtils.copyProperties(knowledgeAdvancedConfig, dim4Dict);
|
||||
}
|
||||
dimensions.add(dim4Dict);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!CollectionUtils.isEmpty(dimensions)) {
|
||||
DimValueDO dimValueDO = new DimValueDO()
|
||||
.setDomainId(domainId)
|
||||
@@ -170,7 +193,6 @@ public class DictMetaUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isVisibleDim(KnowledgeInfo knowledgeInfo, ItemVisibilityInfo itemVisibilityDesc) {
|
||||
if (Objects.isNull(itemVisibilityDesc) || CollectionUtils.isEmpty(itemVisibilityDesc.getBlackDimIdList())) {
|
||||
|
||||
@@ -17,35 +17,36 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Slf4j
|
||||
public class DslToSemanticInfo {
|
||||
|
||||
public 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);
|
||||
protected static final String SUB_TABLE = " ( select * from t_{0} where {1} >= ''{2}'' and {1} <= ''{3}'' ) as t_sub_{0}";
|
||||
|
||||
public static String convert(SemanticParseInfo parseInfo, LLMResp llmResp) {
|
||||
public String convert(SemanticParseInfo parseInfo, LLMResp llmResp, Integer domainId) throws SqlParseException {
|
||||
|
||||
String sqlOutput = llmResp.getSqlOutput();
|
||||
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);
|
||||
|
||||
String tableName = sqlParseInfo.getTableName();
|
||||
List<String> allFields = sqlParseInfo.getAllFields();
|
||||
|
||||
if (StringUtils.isEmpty(domainName)) {
|
||||
domainName = tableName;
|
||||
}
|
||||
|
||||
List<String> allFields = sqlParseInfo.getAllFields();
|
||||
Map<String, Integer> domainNameToId = domainInfos.getDomains().stream()
|
||||
.collect(Collectors.toMap(ItemDO::getName, a -> a.getDomain(), (k1, k2) -> k1));
|
||||
|
||||
Integer domainId = domainNameToId.get(domainName);
|
||||
LOG.info("sqlParseInfo:{} ,domainName:{},domainId:{}", sqlParseInfo, domainName, domainId);
|
||||
// 2. replace the llm dsl, such as replace fieldName and tableName.
|
||||
log.info("sqlParseInfo:{} ,domainName:{},domainId:{}", sqlParseInfo, domainName, domainId);
|
||||
|
||||
DomainInfos domainInfos = ContextUtils.getBean(WordNatureService.class).getCache().getUnchecked("");
|
||||
List<ItemDO> fieldList = domainInfos.getMetrics();
|
||||
fieldList.addAll(domainInfos.getDimensions());
|
||||
Map<String, String> fieldToBizName = getMapInfo(domainId, fieldList);
|
||||
@@ -56,6 +57,7 @@ public class DslToSemanticInfo {
|
||||
sqlOutput = sqlOutput.replaceAll(fieldName, fieldBizName);
|
||||
}
|
||||
}
|
||||
//3. deal with dayNo.
|
||||
DateConf dateInfo = new DateConf();
|
||||
if (Objects.nonNull(parseInfo) && Objects.nonNull(parseInfo.getDateInfo())) {
|
||||
dateInfo = parseInfo.getDateInfo();
|
||||
@@ -72,15 +74,18 @@ public class DslToSemanticInfo {
|
||||
TimeDimensionEnum timeDimension = TimeDimensionEnum.valueOf(period);
|
||||
String dayField = timeDimension.getName();
|
||||
|
||||
// add dayno
|
||||
String subTable = MessageFormat.format(SUB_TABLE, domainId, dayField, startDate, endDate);
|
||||
String querySql = sqlOutput.replaceAll(tableName, subTable);
|
||||
|
||||
LOG.info("querySql:{},sqlOutput:{},dateInfo:{}", querySql, sqlOutput, dateInfo);
|
||||
log.info("querySql:{},sqlOutput:{},dateInfo:{}", querySql, sqlOutput, dateInfo);
|
||||
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))
|
||||
.collect(Collectors.toMap(ItemDO::getName, a -> a.getBizName(), (k1, k2) -> k1));
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package com.tencent.supersonic.chat.infrastructure.repository;
|
||||
|
||||
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.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.pojo.config.*;
|
||||
import com.tencent.supersonic.chat.domain.repository.ChatConfigRepository;
|
||||
import com.tencent.supersonic.chat.domain.utils.ChatConfigUtils;
|
||||
import com.tencent.supersonic.chat.infrastructure.mapper.ChatConfigMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -32,8 +32,8 @@ public class ChatConfigRepositoryImpl implements ChatConfigRepository {
|
||||
@Override
|
||||
public Long createConfig(ChatConfig chaConfig) {
|
||||
ChatConfigDO chaConfigDO = chatConfigUtils.chatConfig2DO(chaConfig);
|
||||
|
||||
return chatConfigMapper.addConfig(chaConfigDO);
|
||||
chatConfigMapper.addConfig(chaConfigDO);
|
||||
return chaConfigDO.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,26 +45,23 @@ public class ChatConfigRepositoryImpl implements ChatConfigRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatConfigInfo> getChatConfig(ChatConfigFilter filter) {
|
||||
List<ChatConfigInfo> chaConfigDescriptorList = new ArrayList<>();
|
||||
public List<ChatConfigResp> getChatConfig(ChatConfigFilter filter) {
|
||||
List<ChatConfigResp> chaConfigDescriptorList = new ArrayList<>();
|
||||
ChatConfigFilterInternal filterInternal = new ChatConfigFilterInternal();
|
||||
BeanUtils.copyProperties(filter, filterInternal);
|
||||
filterInternal.setStatus(filter.getStatus().getCode());
|
||||
List<ChatConfigDO> chaConfigDOList = chatConfigMapper.search(filterInternal);
|
||||
if (!CollectionUtils.isEmpty(chaConfigDOList)) {
|
||||
chaConfigDOList.stream().forEach(chaConfigDO ->
|
||||
chaConfigDescriptorList.add(chatConfigUtils.chatConfigDO2Descriptor(chaConfigDO)));
|
||||
chaConfigDescriptorList.add(chatConfigUtils.chatConfigDO2Descriptor(chaConfigDO.getDomainId(), chaConfigDO)));
|
||||
}
|
||||
return chaConfigDescriptorList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatConfigInfo getConfigByDomainId(Long domainId) {
|
||||
public ChatConfigResp getConfigByDomainId(Long domainId) {
|
||||
ChatConfigDO chaConfigPO = chatConfigMapper.fetchConfigByDomainId(domainId);
|
||||
if (Objects.isNull(chaConfigPO)) {
|
||||
return new ChatConfigInfo();
|
||||
}
|
||||
return chatConfigUtils.chatConfigDO2Descriptor(chaConfigPO);
|
||||
return chatConfigUtils.chatConfigDO2Descriptor(domainId, chaConfigPO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.tencent.supersonic.chat.infrastructure.semantic;
|
||||
|
||||
import com.tencent.supersonic.chat.application.ConfigServiceImpl;
|
||||
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -24,12 +23,21 @@ public class DefaultSemanticConfig {
|
||||
@Value("${fetchDomainSchemaPath.path:/api/semantic/schema}")
|
||||
private String fetchDomainSchemaPath;
|
||||
|
||||
@Autowired
|
||||
private DefaultSemanticInternalUtils defaultSemanticInternalUtils;
|
||||
@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;
|
||||
|
||||
@Value("${fetchDomainList.path:/api/semantic/schema/domain/view/list}")
|
||||
private String fetchDomainViewListPath;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private ConfigServiceImpl chaConfigService;
|
||||
private ConfigServiceImpl configService;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
package com.tencent.supersonic.chat.infrastructure.semantic;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
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.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.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.QueryResultWithSchemaResp;
|
||||
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.*;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
|
||||
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 lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -30,8 +37,21 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
|
||||
private static final Cache<String, List<DomainSchemaResp>> domainSchemaCache =
|
||||
CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
|
||||
|
||||
private SchemaService schemaService;
|
||||
|
||||
private S2ThreadContext s2ThreadContext;
|
||||
|
||||
private DomainService domainService;
|
||||
|
||||
private DimensionService dimensionService;
|
||||
|
||||
private MetricService metricService;
|
||||
|
||||
// public LocalSemanticLayerImpl(DomainService domainService){
|
||||
// this.domainService=domainService;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public QueryResultWithSchemaResp queryByStruct(QueryStructReq queryStructReq, User user) {
|
||||
deletionDuplicated(queryStructReq);
|
||||
@@ -60,6 +80,7 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public List<DomainSchemaResp> fetchDomainSchemaAll(List<Long> ids) {
|
||||
|
||||
DomainSchemaFilterReq filter = new DomainSchemaFilterReq();
|
||||
@@ -71,23 +92,23 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids) {
|
||||
// return domainSchemaCache.get(String.valueOf(ids), () -> {
|
||||
// List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
|
||||
// fillEntityNameAndFilterBlackElement(data);
|
||||
// return data;
|
||||
// });
|
||||
|
||||
public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids, Boolean cacheEnable) {
|
||||
if (cacheEnable) {
|
||||
return domainSchemaCache.get(String.valueOf(ids), () -> {
|
||||
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
|
||||
fillEntityNameAndFilterBlackElement(data);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
|
||||
fillEntityNameAndFilterBlackElement(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainSchemaResp getDomainSchemaInfo(Long domain) {
|
||||
public DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable) {
|
||||
List<Long> ids = new ArrayList<>();
|
||||
ids.add(domain);
|
||||
List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids);
|
||||
List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids, cacheEnable);
|
||||
if (!CollectionUtils.isEmpty(domainSchemaResps)) {
|
||||
Optional<DomainSchemaResp> domainSchemaResp = domainSchemaResps.stream()
|
||||
.filter(d -> d.getId().equals(domain)).findFirst();
|
||||
@@ -101,21 +122,21 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
|
||||
@Override
|
||||
public List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids) {
|
||||
return fetchDomainSchema(ids);
|
||||
return fetchDomainSchema(ids, true);
|
||||
}
|
||||
|
||||
public DomainSchemaResp fillEntityNameAndFilterBlackElement(DomainSchemaResp domainSchemaResp) {
|
||||
if (Objects.isNull(domainSchemaResp) || Objects.isNull(domainSchemaResp.getId())) {
|
||||
return domainSchemaResp;
|
||||
}
|
||||
ChatConfigInfo chaConfigInfo = getConfigBaseInfo(domainSchemaResp.getId());
|
||||
ChatConfigResp chatConfigResp = getConfigBaseInfo(domainSchemaResp.getId());
|
||||
|
||||
// fill entity names
|
||||
fillEntityNamesInfo(domainSchemaResp, chaConfigInfo);
|
||||
fillEntityNamesInfo(domainSchemaResp, chatConfigResp);
|
||||
|
||||
// filter black element
|
||||
filterBlackDim(domainSchemaResp, chaConfigInfo);
|
||||
filterBlackMetric(domainSchemaResp, chaConfigInfo);
|
||||
filterBlackDim(domainSchemaResp, chatConfigResp);
|
||||
filterBlackMetric(domainSchemaResp, chatConfigResp);
|
||||
return domainSchemaResp;
|
||||
}
|
||||
|
||||
@@ -126,9 +147,9 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigInfo chaConfigInfo) {
|
||||
ItemVisibility visibility = chaConfigInfo.getVisibility();
|
||||
if (Objects.nonNull(chaConfigInfo) && Objects.nonNull(visibility)
|
||||
private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigResp) {
|
||||
ItemVisibility visibility = generateFinalVisibility(chatConfigResp);
|
||||
if (Objects.nonNull(chatConfigResp) && Objects.nonNull(visibility)
|
||||
&& !CollectionUtils.isEmpty(visibility.getBlackMetricIdList())
|
||||
&& !CollectionUtils.isEmpty(domainSchemaResp.getMetrics())) {
|
||||
List<MetricSchemaResp> metric4Chat = domainSchemaResp.getMetrics().stream()
|
||||
@@ -138,9 +159,32 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void filterBlackDim(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) {
|
||||
ItemVisibility visibility = chatConfigInfo.getVisibility();
|
||||
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(visibility)
|
||||
private ItemVisibility generateFinalVisibility(ChatConfigResp chatConfigInfo) {
|
||||
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 chatConfigResp) {
|
||||
ItemVisibility visibility = generateFinalVisibility(chatConfigResp);
|
||||
if (Objects.nonNull(chatConfigResp) && Objects.nonNull(visibility)
|
||||
&& !CollectionUtils.isEmpty(visibility.getBlackDimIdList())
|
||||
&& !CollectionUtils.isEmpty(domainSchemaResp.getDimensions())) {
|
||||
List<DimSchemaResp> dim4Chat = domainSchemaResp.getDimensions().stream()
|
||||
@@ -150,10 +194,11 @@ public class LocalSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) {
|
||||
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getEntity())
|
||||
&& !CollectionUtils.isEmpty(chatConfigInfo.getEntity().getNames())) {
|
||||
domainSchemaResp.setEntityNames(chatConfigInfo.getEntity().getNames());
|
||||
private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigResp) {
|
||||
if (Objects.nonNull(chatConfigResp) && Objects.nonNull(chatConfigResp.getChatDetailConfig())
|
||||
&& Objects.nonNull(chatConfigResp.getChatDetailConfig().getEntity())
|
||||
&& !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);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +1,40 @@
|
||||
package com.tencent.supersonic.chat.infrastructure.semantic;
|
||||
|
||||
import static com.tencent.supersonic.common.constant.Constants.TRUE_LOWER;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
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.pojo.User;
|
||||
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.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.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.QueryResultWithSchemaResp;
|
||||
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.*;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QuerySqlReq;
|
||||
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.result.ResultData;
|
||||
import com.tencent.supersonic.common.result.ReturnCode;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
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.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -41,11 +42,27 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
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
|
||||
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 =
|
||||
CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
|
||||
private ParameterizedTypeReference<ResultData<QueryResultWithSchemaResp>> structTypeRef =
|
||||
@@ -70,11 +87,9 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
|
||||
public QueryResultWithSchemaResp searchByRestTemplate(String url, String jsonReq) {
|
||||
DefaultSemanticInternalUtils defaultSemanticInternalUtils = ContextUtils.getBean(
|
||||
DefaultSemanticInternalUtils.class);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
defaultSemanticInternalUtils.fillToken(headers);
|
||||
fillToken(headers);
|
||||
URI requestUrl = UriComponentsBuilder.fromHttpUrl(url).build().encode().toUri();
|
||||
HttpEntity<String> entity = new HttpEntity<>(jsonReq, headers);
|
||||
log.info("url:{},searchByRestTemplate:{}", url, entity.getBody());
|
||||
@@ -102,12 +117,10 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
|
||||
public List<DomainSchemaResp> fetchDomainSchemaAll(List<Long> ids) {
|
||||
DefaultSemanticInternalUtils defaultSemanticInternalUtils = ContextUtils.getBean(
|
||||
DefaultSemanticInternalUtils.class);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set(UserConstants.INTERNAL, TRUE_LOWER);
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
defaultSemanticInternalUtils.fillToken(headers);
|
||||
fillToken(headers);
|
||||
DefaultSemanticConfig defaultSemanticConfig = ContextUtils.getBean(DefaultSemanticConfig.class);
|
||||
|
||||
URI requestUrl = UriComponentsBuilder.fromHttpUrl(
|
||||
@@ -139,19 +152,24 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids) {
|
||||
public List<DomainSchemaResp> fetchDomainSchema(List<Long> ids, Boolean cacheEnable) {
|
||||
if (cacheEnable) {
|
||||
return domainSchemaCache.get(String.valueOf(ids), () -> {
|
||||
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
|
||||
fillEntityNameAndFilterBlackElement(data);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
List<DomainSchemaResp> data = fetchDomainSchemaAll(ids);
|
||||
fillEntityNameAndFilterBlackElement(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainSchemaResp getDomainSchemaInfo(Long domain) {
|
||||
public DomainSchemaResp getDomainSchemaInfo(Long domain, Boolean cacheEnable) {
|
||||
List<Long> ids = new ArrayList<>();
|
||||
ids.add(domain);
|
||||
List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids);
|
||||
List<DomainSchemaResp> domainSchemaResps = fetchDomainSchema(ids, cacheEnable);
|
||||
if (!CollectionUtils.isEmpty(domainSchemaResps)) {
|
||||
Optional<DomainSchemaResp> domainSchemaResp = domainSchemaResps.stream()
|
||||
.filter(d -> d.getId().equals(domain)).findFirst();
|
||||
@@ -165,21 +183,21 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
|
||||
@Override
|
||||
public List<DomainSchemaResp> getDomainSchemaInfo(List<Long> ids) {
|
||||
return fetchDomainSchema(ids);
|
||||
return fetchDomainSchema(ids, true);
|
||||
}
|
||||
|
||||
public DomainSchemaResp fillEntityNameAndFilterBlackElement(DomainSchemaResp domainSchemaResp) {
|
||||
if (Objects.isNull(domainSchemaResp) || Objects.isNull(domainSchemaResp.getId())) {
|
||||
return domainSchemaResp;
|
||||
}
|
||||
ChatConfigInfo chaConfigInfo = getConfigBaseInfo(domainSchemaResp.getId());
|
||||
|
||||
ChatConfigResp chaConfigInfo = getConfigBaseInfo(domainSchemaResp.getId());
|
||||
// fill entity names
|
||||
fillEntityNamesInfo(domainSchemaResp, chaConfigInfo);
|
||||
|
||||
// filter black element
|
||||
filterBlackDim(domainSchemaResp, chaConfigInfo);
|
||||
filterBlackMetric(domainSchemaResp, chaConfigInfo);
|
||||
|
||||
return domainSchemaResp;
|
||||
}
|
||||
|
||||
@@ -190,8 +208,9 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigInfo chaConfigInfo) {
|
||||
ItemVisibility visibility = chaConfigInfo.getVisibility();
|
||||
private void filterBlackMetric(DomainSchemaResp domainSchemaResp, ChatConfigResp chaConfigInfo) {
|
||||
|
||||
ItemVisibility visibility = generateFinalVisibility(chaConfigInfo);
|
||||
if (Objects.nonNull(chaConfigInfo) && Objects.nonNull(visibility)
|
||||
&& !CollectionUtils.isEmpty(visibility.getBlackMetricIdList())
|
||||
&& !CollectionUtils.isEmpty(domainSchemaResp.getMetrics())) {
|
||||
@@ -202,8 +221,31 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void filterBlackDim(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) {
|
||||
ItemVisibility visibility = chatConfigInfo.getVisibility();
|
||||
private ItemVisibility generateFinalVisibility(ChatConfigResp chatConfigInfo) {
|
||||
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)
|
||||
&& !CollectionUtils.isEmpty(visibility.getBlackDimIdList())
|
||||
&& !CollectionUtils.isEmpty(domainSchemaResp.getDimensions())) {
|
||||
@@ -214,10 +256,11 @@ public class RemoteSemanticLayerImpl implements SemanticLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigInfo chatConfigInfo) {
|
||||
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getEntity())
|
||||
&& !CollectionUtils.isEmpty(chatConfigInfo.getEntity().getNames())) {
|
||||
domainSchemaResp.setEntityNames(chatConfigInfo.getEntity().getNames());
|
||||
private void fillEntityNamesInfo(DomainSchemaResp domainSchemaResp, ChatConfigResp chatConfigInfo) {
|
||||
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getChatDetailConfig())
|
||||
&& Objects.nonNull(chatConfigInfo.getChatDetailConfig().getEntity())
|
||||
&& !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);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,18 +3,19 @@ package com.tencent.supersonic.chat.rest;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.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.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.domain.pojo.config.ChatConfigBase;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigEditReq;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigBaseReq;
|
||||
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.ChatConfigInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichInfo;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.domain.pojo.config.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.domain.service.ConfigService;
|
||||
import com.tencent.supersonic.chat.domain.utils.DefaultSemanticInternalUtils;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -37,12 +38,12 @@ public class ChatConfigController {
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private DefaultSemanticInternalUtils defaultSemanticUtils;
|
||||
|
||||
private SemanticLayer semanticLayer = ComponentFactory.getSemanticLayer();
|
||||
|
||||
|
||||
@PostMapping
|
||||
public Long addChatConfig(@RequestBody ChatConfigBase extendBaseCmd,
|
||||
public Long addChatConfig(@RequestBody ChatConfigBaseReq extendBaseCmd,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
@@ -50,7 +51,7 @@ public class ChatConfigController {
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public Long editDomainExtend(@RequestBody ChatConfigEditReq extendEditCmd,
|
||||
public Long editDomainExtend(@RequestBody ChatConfigEditReqReq extendEditCmd,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
@@ -59,7 +60,7 @@ public class ChatConfigController {
|
||||
|
||||
|
||||
@PostMapping("/search")
|
||||
public List<ChatConfigInfo> search(@RequestBody ChatConfigFilter filter,
|
||||
public List<ChatConfigResp> search(@RequestBody ChatConfigFilter filter,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
@@ -68,12 +69,12 @@ public class ChatConfigController {
|
||||
|
||||
|
||||
@GetMapping("/richDesc/{domainId}")
|
||||
public ChatConfigRichInfo getDomainExtendRichInfo(@PathVariable("domainId") Long domainId) {
|
||||
public ChatConfigRichResp getDomainExtendRichInfo(@PathVariable("domainId") Long domainId) {
|
||||
return configService.getConfigRichInfo(domainId);
|
||||
}
|
||||
|
||||
@GetMapping("/richDesc/all")
|
||||
public List<ChatConfigRichInfo> getAllChatRichConfig() {
|
||||
public List<ChatConfigRichResp> getAllChatRichConfig() {
|
||||
return configService.getAllChatRichConfig();
|
||||
}
|
||||
|
||||
@@ -85,23 +86,29 @@ public class ChatConfigController {
|
||||
*/
|
||||
@GetMapping("/domainList")
|
||||
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")
|
||||
public PageInfo<DimensionResp> queryDimension(@RequestBody PageDimensionReq pageDimensionCmd,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return defaultSemanticUtils.queryDimensionPage(pageDimensionCmd, user);
|
||||
return semanticLayer.queryDimensionPage(pageDimensionCmd);
|
||||
}
|
||||
|
||||
@PostMapping("/metric/page")
|
||||
public PageInfo<MetricResp> queryMetric(@RequestBody PageMetricReq pageMetrricCmd,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return defaultSemanticUtils.queryMetricPage(pageMetrricCmd, user);
|
||||
return semanticLayer.queryMetricPage(pageMetrricCmd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
chat/core/src/main/python/bin/env.sh
Normal file
10
chat/core/src/main/python/bin/env.sh
Normal 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
|
||||
22
chat/core/src/main/python/bin/install.sh
Executable file
22
chat/core/src/main/python/bin/install.sh
Executable 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
|
||||
31
chat/core/src/main/python/bin/run.sh
Executable file
31
chat/core/src/main/python/bin/run.sh
Executable 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 &
|
||||
53
chat/core/src/main/python/bin/service.sh
Executable file
53
chat/core/src/main/python/bin/service.sh
Executable 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
|
||||
33
chat/core/src/main/python/llm/api_service.py
Normal file
33
chat/core/src/main/python/llm/api_service.py
Normal 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
|
||||
147
chat/core/src/main/python/llm/few_shot_example/sql_exampler.py
Normal file
147
chat/core/src/main/python/llm/few_shot_example/sql_exampler.py
Normal 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 歌手名 = '陈奕迅'"""
|
||||
}
|
||||
]
|
||||
15
chat/core/src/main/python/llm/sql/output_parser.py
Normal file
15
chat/core/src/main/python/llm/sql/output_parser.py
Normal 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
|
||||
88
chat/core/src/main/python/llm/sql/prompt_maker.py
Normal file
88
chat/core/src/main/python/llm/sql/prompt_maker.py
Normal 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
|
||||
48
chat/core/src/main/python/llm/sql/run.py
Normal file
48
chat/core/src/main/python/llm/sql/run.py
Normal 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
|
||||
8
chat/core/src/main/python/requirements.txt
Normal file
8
chat/core/src/main/python/requirements.txt
Normal 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
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
type="com.tencent.supersonic.chat.domain.dataobject.ChatConfigDO">
|
||||
<id column="id" property="id"/>
|
||||
<result column="domain_id" property="domainId"/>
|
||||
<result column="default_metrics" property="defaultMetrics"/>
|
||||
<result column="visibility" property="visibility"/>
|
||||
<result column="entity_info" property="entity"/>
|
||||
<result column="dictionary_info" property="knowledgeInfo"/>
|
||||
<result column="chat_detail_config" property="chatDetailConfig"/>
|
||||
<result column="chat_agg_config" property="chatAggConfig"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="created_by" property="createdBy"/>
|
||||
<result column="updated_by" property="updatedBy"/>
|
||||
@@ -25,11 +23,11 @@
|
||||
useGeneratedKeys="true" keyProperty="id">
|
||||
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
|
||||
(
|
||||
#{domainId}, #{defaultMetrics}, #{visibility}, #{entity}, #{knowledgeInfo}, #{status}, #{createdBy}, #{updatedBy}, #{createdAt}, #{updatedAt}
|
||||
#{domainId}, #{chatDetailConfig}, #{chatAggConfig}, #{status}, #{createdBy}, #{updatedBy}, #{createdAt}, #{updatedAt}
|
||||
)
|
||||
</insert>
|
||||
|
||||
@@ -38,18 +36,11 @@
|
||||
update s2_chat_config
|
||||
<set>
|
||||
`updated_at` = #{updatedAt} ,
|
||||
|
||||
<if test="defaultMetrics != null and defaultMetrics != ''">
|
||||
`default_metrics` = #{defaultMetrics} ,
|
||||
<if test="chatDetailConfig != null and chatDetailConfig != ''">
|
||||
`chat_detail_config` = #{chatDetailConfig} ,
|
||||
</if>
|
||||
<if test="visibility != null and visibility != ''">
|
||||
visibility = #{visibility} ,
|
||||
</if>
|
||||
<if test="entity != null and entity != ''">
|
||||
entity_info = #{entity} ,
|
||||
</if>
|
||||
<if test="knowledgeInfo != null and knowledgeInfo != ''">
|
||||
`dictionary_info` = #{knowledgeInfo} ,
|
||||
<if test="chatAggConfig != null and chatAggConfig != ''">
|
||||
chat_agg_config = #{chatAggConfig} ,
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
status = #{status} ,
|
||||
@@ -90,7 +81,8 @@
|
||||
select *
|
||||
from s2_chat_config
|
||||
where domain_id = #{domainId}
|
||||
order by status
|
||||
and status != 3
|
||||
order by updated_at desc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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.MetricSchemaResp;
|
||||
import com.tencent.supersonic.chat.application.ConfigServiceImpl;
|
||||
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.ChatConfigResp;
|
||||
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.DefaultMetricInfo;
|
||||
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,
|
||||
List<MetricSchemaResp> metricDescs) {
|
||||
ChatConfigRichInfo chaConfigRichDesc = new ChatConfigRichInfo();
|
||||
ChatConfigRichResp chaConfigRichDesc = new ChatConfigRichResp();
|
||||
DefaultMetric defaultMetricDesc = new DefaultMetric();
|
||||
defaultMetricDesc.setUnit(3);
|
||||
defaultMetricDesc.setPeriod(Constants.DAY);
|
||||
chaConfigRichDesc.setDefaultMetrics(new ArrayList<>(Arrays.asList(defaultMetricDesc)));
|
||||
// chaConfigRichDesc.setDefaultMetrics(new ArrayList<>(Arrays.asList(defaultMetricDesc)));
|
||||
EntityRichInfo entityDesc = new EntityRichInfo();
|
||||
List<DimSchemaResp> dimensionDescs1 = new ArrayList<>();
|
||||
DimSchemaResp dimensionDesc = new DimSchemaResp();
|
||||
dimensionDesc.setId(162L);
|
||||
dimensionDescs1.add(dimensionDesc);
|
||||
entityDesc.setEntityIds(dimensionDescs1);
|
||||
// entityDesc.setEntityIds(dimensionDescs1);
|
||||
|
||||
DimSchemaResp dimensionDesc2 = new DimSchemaResp();
|
||||
dimensionDesc2.setId(163L);
|
||||
@@ -71,14 +71,14 @@ public class MockBeansConfiguration {
|
||||
metricDesc.setBizName("js_play_cnt");
|
||||
metricDesc.setName("结算播放量");
|
||||
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);
|
||||
DomainSchemaResp domainSchemaDesc = new DomainSchemaResp();
|
||||
domainSchemaDesc.setDimensions(dimensionDescs);
|
||||
domainSchemaDesc.setMetrics(metricDescs);
|
||||
when(httpSemanticLayer.getDomainSchemaInfo(anyLong())).thenReturn(domainSchemaDesc);
|
||||
// when(httpSemanticLayer.getDomainSchemaInfo(anyLong())).thenReturn(domainSchemaDesc);
|
||||
|
||||
DomainInfos domainInfos = new DomainInfos();
|
||||
when(SchemaInfoConverter.convert(httpSemanticLayer.getDomainSchemaInfo(anyList()))).thenReturn(domainInfos);
|
||||
@@ -92,8 +92,8 @@ public class MockBeansConfiguration {
|
||||
List<DefaultMetricInfo> defaultMetricInfos = new ArrayList<>();
|
||||
defaultMetricInfos.add(defaultMetricInfo);
|
||||
|
||||
ChatConfigInfo chaConfigDesc = new ChatConfigInfo();
|
||||
chaConfigDesc.setDefaultMetrics(defaultMetricInfos);
|
||||
ChatConfigResp chaConfigDesc = new ChatConfigResp();
|
||||
// chaConfigDesc.setDefaultMetrics(defaultMetricInfos);
|
||||
when(configService.fetchConfigByDomainId(anyLong())).thenReturn(chaConfigDesc);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,12 @@ import com.hankcs.hanlp.seg.common.Term;
|
||||
import com.hankcs.hanlp.seg.common.Vertex;
|
||||
import com.hankcs.hanlp.seg.common.WordNet;
|
||||
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 {
|
||||
|
||||
|
||||
@@ -6,12 +6,15 @@ import com.hankcs.hanlp.HanLP;
|
||||
import com.hankcs.hanlp.dictionary.CoreDictionary;
|
||||
import com.hankcs.hanlp.dictionary.DynamicCustomDictionary;
|
||||
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.NatureType;
|
||||
import com.tencent.supersonic.common.nlp.WordNature;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public class DateConf {
|
||||
private static final long serialVersionUID = 3074129990945004340L;
|
||||
|
||||
|
||||
private DateMode dateMode;
|
||||
private DateMode dateMode = DateMode.RECENT_UNITS;
|
||||
|
||||
/**
|
||||
* like 2021-10-22, dateMode=1
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
package com.tencent.supersonic.common.util.calcite;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.calcite.sql.SqlBasicCall;
|
||||
import org.apache.calcite.sql.SqlDialect;
|
||||
import org.apache.calcite.sql.SqlIdentifier;
|
||||
import org.apache.calcite.sql.SqlKind;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.SqlNodeList;
|
||||
import org.apache.calcite.sql.SqlOrderBy;
|
||||
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.SqlParser;
|
||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||
import org.apache.calcite.sql.util.SqlString;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
/**
|
||||
* sql parse utils
|
||||
@@ -28,11 +36,14 @@ public class SqlParseUtils {
|
||||
SqlParser parser = SqlParser.create(sql);
|
||||
SqlNode sqlNode = parser.parseQuery();
|
||||
SqlParserInfo sqlParserInfo = new 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;
|
||||
} catch (SqlParseException e) {
|
||||
throw new RuntimeException("getSqlParseInfo", e);
|
||||
@@ -69,7 +80,8 @@ public class SqlParseUtils {
|
||||
SqlNode query = sqlOrderBy.query;
|
||||
handlerSQL(query, sqlParserInfo);
|
||||
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;
|
||||
SqlNodeList selectList = sqlSelect.getSelectList();
|
||||
|
||||
List<String> allFields = sqlParserInfo.getAllFields();
|
||||
|
||||
selectList.getList().forEach(list -> {
|
||||
handlerField(list, sqlParserInfo);
|
||||
Set<String> selectFields = handlerField(list);
|
||||
sqlParserInfo.getSelectFields().addAll(selectFields);
|
||||
allFields.addAll(selectFields);
|
||||
});
|
||||
String tableName = handlerFrom(sqlSelect.getFrom());
|
||||
sqlParserInfo.setTableName(tableName);
|
||||
|
||||
if (sqlSelect.hasWhere()) {
|
||||
handlerField(sqlSelect.getWhere(), sqlParserInfo);
|
||||
allFields.addAll(handlerField(sqlSelect.getWhere()));
|
||||
}
|
||||
if (sqlSelect.hasOrderBy()) {
|
||||
handlerField(sqlSelect.getOrderList(), sqlParserInfo);
|
||||
allFields.addAll(handlerField(sqlSelect.getOrderList()));
|
||||
}
|
||||
SqlNodeList group = sqlSelect.getGroup();
|
||||
if (group != null) {
|
||||
group.forEach(groupField -> {
|
||||
handlerField(groupField, sqlParserInfo);
|
||||
allFields.addAll(handlerField(groupField));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -127,34 +143,120 @@ public class SqlParseUtils {
|
||||
* handler 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();
|
||||
switch (kind) {
|
||||
case AS:
|
||||
List<SqlNode> operandList1 = ((SqlBasicCall) field).getOperandList();
|
||||
SqlNode left_as = operandList1.get(0);
|
||||
handlerField(left_as, sqlParserInfo);
|
||||
SqlNode leftAs = operandList1.get(0);
|
||||
fields.addAll(handlerField(leftAs));
|
||||
break;
|
||||
case IDENTIFIER:
|
||||
SqlIdentifier sqlIdentifier = (SqlIdentifier) field;
|
||||
sqlParserInfo.getAllFields().add(sqlIdentifier.getSimple());
|
||||
fields.add(sqlIdentifier.getSimple());
|
||||
break;
|
||||
default:
|
||||
if (field instanceof SqlBasicCall) {
|
||||
List<SqlNode> operandList2 = ((SqlBasicCall) field).getOperandList();
|
||||
for (int i = 0; i < operandList2.size(); i++) {
|
||||
handlerField(operandList2.get(i), sqlParserInfo);
|
||||
fields.addAll(handlerField(operandList2.get(i)));
|
||||
}
|
||||
}
|
||||
if (field instanceof SqlNodeList) {
|
||||
((SqlNodeList) field).getList().forEach(node -> {
|
||||
handlerField(node, sqlParserInfo);
|
||||
fields.addAll(handlerField(node));
|
||||
});
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ public class SqlParserInfo implements Serializable {
|
||||
|
||||
private String tableName;
|
||||
|
||||
private List<String> allFields = new ArrayList<>();
|
||||
private List<String> selectFields = new ArrayList<>();
|
||||
|
||||
private List<String> allFields = new ArrayList<>();
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ baseDir=$(readlink -f $binDir/../)
|
||||
confDir=$baseDir/conf
|
||||
source ${baseDir}/bin/env.sh
|
||||
|
||||
commond=$1
|
||||
command=$1
|
||||
|
||||
function start()
|
||||
{
|
||||
@@ -33,7 +33,7 @@ function stop()
|
||||
fi
|
||||
}
|
||||
|
||||
case "$commond" in
|
||||
case "$command" in
|
||||
start)
|
||||
echo -e "Starting $APP_NAME"
|
||||
start
|
||||
|
||||
@@ -6,8 +6,8 @@ com.tencent.supersonic.chat.api.component.SchemaMapper=\
|
||||
com.tencent.supersonic.chat.api.component.SemanticParser=\
|
||||
com.tencent.supersonic.chat.application.parser.DomainSemanticParser, \
|
||||
com.tencent.supersonic.chat.application.parser.TimeSemanticParser, \
|
||||
com.tencent.supersonic.chat.application.parser.AggregateSemanticParser
|
||||
# com.tencent.supersonic.chat.application.parser.LLMSemanticParser
|
||||
com.tencent.supersonic.chat.application.parser.AggregateSemanticParser, \
|
||||
com.tencent.supersonic.chat.application.parser.LLMSemanticParser
|
||||
|
||||
|
||||
com.tencent.supersonic.chat.api.component.SemanticLayer=\
|
||||
|
||||
@@ -5,3 +5,15 @@ dean _1_2 36
|
||||
john _1_2 50
|
||||
jack _1_2 38
|
||||
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
|
||||
|
||||
@@ -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 (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 (2, '用户访问统计','2023-06-10 10:01:04.528','2023-06-10 10:01:04','admin','您好,欢迎使用内容智能小Q','0','0');
|
||||
|
||||
@@ -37,15 +37,11 @@ CREATE TABLE `s2_chat_query`
|
||||
PRIMARY KEY (`question_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
|
||||
`chat_detail_config` varchar(655) ,
|
||||
`chat_agg_config` varchar(655) ,
|
||||
`created_at` TIMESTAMP NOT NULL ,
|
||||
`updated_at` TIMESTAMP 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
|
||||
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 ';
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptors>
|
||||
<descriptor>../../assembly/build/build.xml</descriptor>
|
||||
<descriptor>../semantic/src/main/build/build.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
|
||||
@@ -5,7 +5,7 @@ baseDir=$(readlink -f $binDir/../)
|
||||
confDir=$baseDir/conf
|
||||
source ${baseDir}/bin/env.sh
|
||||
|
||||
commond=$1
|
||||
command=$1
|
||||
|
||||
function start()
|
||||
{
|
||||
@@ -33,7 +33,7 @@ function stop()
|
||||
fi
|
||||
}
|
||||
|
||||
case "$commond" in
|
||||
case "$command" in
|
||||
start)
|
||||
echo -e "Starting $APP_NAME"
|
||||
start
|
||||
|
||||
39
launchers/semantic/src/main/build/build.xml
Normal file
39
launchers/semantic/src/main/build/build.xml
Normal 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>
|
||||
@@ -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(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(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(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(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_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(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_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(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_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, '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(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` )
|
||||
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 ('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', -4, CURRENT_DATE()), 'jack', 'p1');
|
||||
|
||||
@@ -211,6 +211,7 @@ CREATE TABLE IF NOT EXISTS `s2_available_date_info` (
|
||||
`created_by` varchar(100) NOT NULL ,
|
||||
`updated_at` TIMESTAMP 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
|
||||
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';
|
||||
|
||||
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';
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export APP_NAME=chat-service
|
||||
export MAIN_CLASS=com.tencent.supersonic.Launcher
|
||||
export MAIN_CLASS=com.tencent.supersonic.StandaloneLauncher
|
||||
|
||||
@@ -5,7 +5,7 @@ baseDir=$(readlink -f $binDir/../)
|
||||
confDir=$baseDir/conf
|
||||
source ${baseDir}/bin/env.sh
|
||||
|
||||
commond=$1
|
||||
command=$1
|
||||
|
||||
function start()
|
||||
{
|
||||
@@ -33,7 +33,7 @@ function stop()
|
||||
fi
|
||||
}
|
||||
|
||||
case "$commond" in
|
||||
case "$command" in
|
||||
start)
|
||||
echo -e "Starting $APP_NAME"
|
||||
start
|
||||
|
||||
@@ -6,8 +6,8 @@ com.tencent.supersonic.chat.api.component.SchemaMapper=\
|
||||
com.tencent.supersonic.chat.api.component.SemanticParser=\
|
||||
com.tencent.supersonic.chat.application.parser.DomainSemanticParser, \
|
||||
com.tencent.supersonic.chat.application.parser.TimeSemanticParser, \
|
||||
com.tencent.supersonic.chat.application.parser.AggregateSemanticParser
|
||||
# com.tencent.supersonic.chat.application.parser.LLMSemanticParser
|
||||
com.tencent.supersonic.chat.application.parser.AggregateSemanticParser, \
|
||||
com.tencent.supersonic.chat.application.parser.LLMSemanticParser
|
||||
|
||||
|
||||
com.tencent.supersonic.chat.api.component.SemanticLayer=\
|
||||
|
||||
@@ -16,7 +16,7 @@ server:
|
||||
port: 9080
|
||||
|
||||
authentication:
|
||||
enable: false
|
||||
enable: true
|
||||
exclude:
|
||||
path: /api/auth/user/register,/api/auth/user/login
|
||||
|
||||
|
||||
@@ -5,3 +5,15 @@ dean _1_2 36
|
||||
john _1_2 50
|
||||
jack _1_2 38
|
||||
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
|
||||
|
||||
@@ -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 (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 (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
|
||||
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(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(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(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_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(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(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(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(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` )
|
||||
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)
|
||||
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 s2_user (id, `name`, password, display_name, email) values (2, 'jack','123456','jack','jack@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 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);
|
||||
|
||||
---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 ('tom','sales');
|
||||
insert into s2_user_department (user_name, department) values ('lucy','marketing');
|
||||
|
||||
@@ -39,14 +39,11 @@ CREATE TABLE `s2_chat_query`
|
||||
);
|
||||
|
||||
|
||||
|
||||
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
|
||||
`chat_detail_config` varchar(655) ,
|
||||
`chat_agg_config` varchar(655) ,
|
||||
`created_at` TIMESTAMP NOT NULL ,
|
||||
`updated_at` TIMESTAMP NOT NULL ,
|
||||
`created_by` varchar(100) NOT NULL ,
|
||||
@@ -306,6 +303,7 @@ CREATE TABLE IF NOT EXISTS `s2_available_date_info` (
|
||||
`created_by` varchar(100) NOT NULL ,
|
||||
`updated_at` TIMESTAMP 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
|
||||
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';
|
||||
|
||||
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';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.tencent.supersonic.db;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
|
||||
@Configuration
|
||||
@MapperScan(value = "com.tencent.supersonic", annotationClass = Mapper.class)
|
||||
public class MybatisConfig {
|
||||
|
||||
private static final String MAPPER_LOCATION = "classpath*:mapper/**/*.xml";
|
||||
|
||||
@Bean
|
||||
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
|
||||
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
|
||||
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
|
||||
configuration.setMapUnderscoreToCamelCase(true);
|
||||
bean.setConfiguration(configuration);
|
||||
bean.setDataSource(dataSource);
|
||||
|
||||
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
|
||||
return bean.getObject();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user