mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-15 14:36:47 +00:00
(improvement)(chat) Split chat into three modules: server, api, and core. (#594)
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
package com.tencent.supersonic.chat.server.config;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatAggConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatDetailConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.pojo.RecordInfo;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class ChatConfig {
|
||||
|
||||
/**
|
||||
* database auto-increment primary key
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
private Long modelId;
|
||||
|
||||
/**
|
||||
* the chatDetailConfig about the model
|
||||
*/
|
||||
private ChatDetailConfigReq chatDetailConfig;
|
||||
|
||||
/**
|
||||
* the chatAggConfig about the model
|
||||
*/
|
||||
private ChatAggConfigReq chatAggConfig;
|
||||
|
||||
private List<RecommendedQuestionReq> recommendedQuestions;
|
||||
|
||||
/**
|
||||
* available status
|
||||
*/
|
||||
private StatusEnum status;
|
||||
|
||||
/**
|
||||
* about createdBy, createdAt, updatedBy, updatedAt
|
||||
*/
|
||||
private RecordInfo recordInfo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.tencent.supersonic.chat.server.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ChatConfigFilterInternal {
|
||||
|
||||
private Long id;
|
||||
private Long modelId;
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.tencent.supersonic.chat.server.listener;
|
||||
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictWord;
|
||||
import com.tencent.supersonic.chat.server.service.KnowledgeService;
|
||||
import com.tencent.supersonic.chat.server.service.impl.SchemaService;
|
||||
import com.tencent.supersonic.chat.server.service.impl.WordService;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@Order(2)
|
||||
public class ApplicationStartedListener implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private KnowledgeService knowledgeService;
|
||||
@Autowired
|
||||
private WordService wordService;
|
||||
@Autowired
|
||||
private SchemaService schemaService;
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
updateKnowledgeDimValue();
|
||||
}
|
||||
|
||||
public Boolean updateKnowledgeDimValue() {
|
||||
Boolean isOk = false;
|
||||
try {
|
||||
log.debug("ApplicationStartedInit start");
|
||||
|
||||
List<DictWord> dictWords = wordService.getAllDictWords();
|
||||
wordService.setPreDictWords(dictWords);
|
||||
knowledgeService.reloadAllData(dictWords);
|
||||
|
||||
log.debug("ApplicationStartedInit end");
|
||||
isOk = true;
|
||||
} catch (Exception e) {
|
||||
log.error("ApplicationStartedInit error", e);
|
||||
}
|
||||
return isOk;
|
||||
}
|
||||
|
||||
public Boolean updateKnowledgeDimValueAsync() {
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
updateKnowledgeDimValue();
|
||||
return null;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/***
|
||||
* reload knowledge task
|
||||
*/
|
||||
@Scheduled(cron = "${reload.knowledge.corn:0 0/1 * * * ?}")
|
||||
public void reloadKnowledge() {
|
||||
log.debug("reloadKnowledge start");
|
||||
|
||||
try {
|
||||
List<DictWord> dictWords = wordService.getAllDictWords();
|
||||
List<DictWord> preDictWords = wordService.getPreDictWords();
|
||||
|
||||
if (CollectionUtils.isEqualCollection(dictWords, preDictWords)) {
|
||||
log.debug("dictWords has not changed, reloadKnowledge end");
|
||||
return;
|
||||
}
|
||||
log.info("dictWords has changed");
|
||||
wordService.setPreDictWords(dictWords);
|
||||
knowledgeService.updateOnlineKnowledge(wordService.getAllDictWords());
|
||||
schemaService.getCache().refresh(SchemaService.ALL_CACHE);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("reloadKnowledge error", e);
|
||||
}
|
||||
|
||||
log.debug("reloadKnowledge end");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.tencent.supersonic.chat.server.listener;
|
||||
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictWord;
|
||||
import com.tencent.supersonic.chat.core.utils.HanlpHelper;
|
||||
import com.tencent.supersonic.chat.server.service.impl.SchemaService;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.DataEvent;
|
||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||
import com.tencent.supersonic.common.pojo.enums.EventType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SchemaDictUpdateListener implements ApplicationListener<DataEvent> {
|
||||
|
||||
@Autowired
|
||||
private SchemaService schemaService;
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void onApplicationEvent(DataEvent dataEvent) {
|
||||
if (CollectionUtils.isEmpty(dataEvent.getDataItems())) {
|
||||
return;
|
||||
}
|
||||
schemaService.getCache().invalidateAll();
|
||||
dataEvent.getDataItems().forEach(dataItem -> {
|
||||
DictWord dictWord = new DictWord();
|
||||
dictWord.setWord(dataItem.getName());
|
||||
String sign = DictWordType.NATURE_SPILT;
|
||||
String nature = sign + dataItem.getModelId() + sign + dataItem.getId()
|
||||
+ sign + dataItem.getType().getName();
|
||||
String natureWithFrequency = nature + " " + Constants.DEFAULT_FREQUENCY;
|
||||
dictWord.setNature(nature);
|
||||
dictWord.setNatureWithFrequency(natureWithFrequency);
|
||||
if (EventType.ADD.equals(dataEvent.getEventType())) {
|
||||
HanlpHelper.addToCustomDictionary(dictWord);
|
||||
} else if (EventType.DELETE.equals(dataEvent.getEventType())) {
|
||||
HanlpHelper.removeFromCustomDictionary(dictWord);
|
||||
} else if (EventType.UPDATE.equals(dataEvent.getEventType())) {
|
||||
HanlpHelper.removeFromCustomDictionary(dictWord);
|
||||
dictWord.setWord(dataItem.getNewName());
|
||||
HanlpHelper.addToCustomDictionary(dictWord);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class AgentDO {
|
||||
/**
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 0 offline, 1 online
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String examples;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String config;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Date createdAt;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String updatedBy;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Date updatedAt;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Integer enableSearch;
|
||||
|
||||
/**
|
||||
* @return id
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name == null ? null : name.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param description
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description == null ? null : description.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 0 offline, 1 online
|
||||
* @return status 0 offline, 1 online
|
||||
*/
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 0 offline, 1 online
|
||||
* @param status 0 offline, 1 online
|
||||
*/
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return examples
|
||||
*/
|
||||
public String getExamples() {
|
||||
return examples;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param examples
|
||||
*/
|
||||
public void setExamples(String examples) {
|
||||
this.examples = examples == null ? null : examples.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return config
|
||||
*/
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param config
|
||||
*/
|
||||
public void setConfig(String config) {
|
||||
this.config = config == null ? null : config.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return created_by
|
||||
*/
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param createdBy
|
||||
*/
|
||||
public void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy == null ? null : createdBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return created_at
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param createdAt
|
||||
*/
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return updated_by
|
||||
*/
|
||||
public String getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param updatedBy
|
||||
*/
|
||||
public void setUpdatedBy(String updatedBy) {
|
||||
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return updated_at
|
||||
*/
|
||||
public Date getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param updatedAt
|
||||
*/
|
||||
public void setUpdatedAt(Date updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return enable_search
|
||||
*/
|
||||
public Integer getEnableSearch() {
|
||||
return enableSearch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enableSearch
|
||||
*/
|
||||
public void setEnableSearch(Integer enableSearch) {
|
||||
this.enableSearch = enableSearch;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class ChatConfigDO {
|
||||
|
||||
/**
|
||||
* database auto-increment primary key
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
private Long modelId;
|
||||
|
||||
private String chatDetailConfig;
|
||||
|
||||
private String chatAggConfig;
|
||||
|
||||
private String recommendedQuestions;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String llmExamples;
|
||||
|
||||
/**
|
||||
* record info
|
||||
*/
|
||||
private String createdBy;
|
||||
private String updatedBy;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ChatContextDO implements Serializable {
|
||||
|
||||
private Integer chatId;
|
||||
private Instant modifiedAt;
|
||||
private String user;
|
||||
private String queryText;
|
||||
private String semanticParse;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ChatDO {
|
||||
|
||||
private long chatId;
|
||||
private Integer agentId;
|
||||
private String chatName;
|
||||
private String createTime;
|
||||
private String lastTime;
|
||||
private String creator;
|
||||
private String lastQuestion;
|
||||
private int isDelete;
|
||||
private int isTop;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class ChatParseDO {
|
||||
|
||||
/**
|
||||
* questionId
|
||||
*/
|
||||
private Long questionId;
|
||||
|
||||
/**
|
||||
* chatId
|
||||
*/
|
||||
private Long chatId;
|
||||
|
||||
/**
|
||||
* parseId
|
||||
*/
|
||||
private Integer parseId;
|
||||
|
||||
/**
|
||||
* createTime
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* queryText
|
||||
*/
|
||||
private String queryText;
|
||||
|
||||
/**
|
||||
* userName
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
|
||||
/**
|
||||
* parseInfo
|
||||
*/
|
||||
private String parseInfo;
|
||||
|
||||
/**
|
||||
* isCandidate
|
||||
*/
|
||||
private Integer isCandidate;
|
||||
|
||||
/**
|
||||
* return question_id
|
||||
*/
|
||||
public Long getQuestionId() {
|
||||
return questionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* questionId
|
||||
*/
|
||||
public void setQuestionId(Long questionId) {
|
||||
this.questionId = questionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* return create_time
|
||||
*/
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* createTime
|
||||
*/
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* return user_name
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* userName
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName == null ? null : userName.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* return chat_id
|
||||
*/
|
||||
public Long getChatId() {
|
||||
return chatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* chatId
|
||||
*/
|
||||
public void setChatId(Long chatId) {
|
||||
this.chatId = chatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* return query_text
|
||||
*/
|
||||
public String getQueryText() {
|
||||
return queryText;
|
||||
}
|
||||
|
||||
/**
|
||||
* queryText
|
||||
*/
|
||||
public void setQueryText(String queryText) {
|
||||
this.queryText = queryText == null ? null : queryText.trim();
|
||||
}
|
||||
|
||||
public Integer getIsCandidate() {
|
||||
return isCandidate;
|
||||
}
|
||||
|
||||
public Integer getParseId() {
|
||||
return parseId;
|
||||
}
|
||||
|
||||
public String getParseInfo() {
|
||||
return parseInfo;
|
||||
}
|
||||
|
||||
public void setParseId(Integer parseId) {
|
||||
this.parseId = parseId;
|
||||
}
|
||||
|
||||
public void setIsCandidate(Integer isCandidate) {
|
||||
this.isCandidate = isCandidate;
|
||||
}
|
||||
|
||||
public void setParseInfo(String parseInfo) {
|
||||
this.parseInfo = parseInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class ChatQueryDO {
|
||||
/**
|
||||
*/
|
||||
private Long questionId;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Integer agentId;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Integer queryState;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Long chatId;
|
||||
|
||||
/**
|
||||
*/
|
||||
private Integer score;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String feedback;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String queryText;
|
||||
|
||||
/**
|
||||
*/
|
||||
private String queryResult;
|
||||
|
||||
private String similarQueries;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,790 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class ChatQueryDOExample {
|
||||
/**
|
||||
* s2_chat_query
|
||||
*/
|
||||
protected String orderByClause;
|
||||
|
||||
/**
|
||||
* s2_chat_query
|
||||
*/
|
||||
protected boolean distinct;
|
||||
|
||||
/**
|
||||
* s2_chat_query
|
||||
*/
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
/**
|
||||
* s2_chat_query
|
||||
*/
|
||||
protected Integer limitStart;
|
||||
|
||||
/**
|
||||
* s2_chat_query
|
||||
*/
|
||||
protected Integer limitEnd;
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public ChatQueryDOExample() {
|
||||
oredCriteria = new ArrayList<Criteria>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setOrderByClause(String orderByClause) {
|
||||
this.orderByClause = orderByClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public String getOrderByClause() {
|
||||
return orderByClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setDistinct(boolean distinct) {
|
||||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public boolean isDistinct() {
|
||||
return distinct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public List<Criteria> getOredCriteria() {
|
||||
return oredCriteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void or(Criteria criteria) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Criteria or() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
oredCriteria.add(criteria);
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Criteria createCriteria() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
if (oredCriteria.size() == 0) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
protected Criteria createCriteriaInternal() {
|
||||
Criteria criteria = new Criteria();
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void clear() {
|
||||
oredCriteria.clear();
|
||||
orderByClause = null;
|
||||
distinct = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setLimitStart(Integer limitStart) {
|
||||
this.limitStart = limitStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Integer getLimitStart() {
|
||||
return limitStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setLimitEnd(Integer limitEnd) {
|
||||
this.limitEnd = limitEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Integer getLimitEnd() {
|
||||
return limitEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* s2_chat_query null
|
||||
*/
|
||||
protected abstract static class GeneratedCriteria {
|
||||
protected List<Criterion> criteria;
|
||||
|
||||
protected GeneratedCriteria() {
|
||||
super();
|
||||
criteria = new ArrayList<Criterion>();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return criteria.size() > 0;
|
||||
}
|
||||
|
||||
public List<Criterion> getAllCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public List<Criterion> getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition) {
|
||||
if (condition == null) {
|
||||
throw new RuntimeException("Value for condition cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value, String property) {
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||
if (value1 == null || value2 == null) {
|
||||
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value1, value2));
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdIsNull() {
|
||||
addCriterion("question_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdIsNotNull() {
|
||||
addCriterion("question_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdEqualTo(Long value) {
|
||||
addCriterion("question_id =", value, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdNotEqualTo(Long value) {
|
||||
addCriterion("question_id <>", value, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdGreaterThan(Long value) {
|
||||
addCriterion("question_id >", value, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("question_id >=", value, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdLessThan(Long value) {
|
||||
addCriterion("question_id <", value, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdLessThanOrEqualTo(Long value) {
|
||||
addCriterion("question_id <=", value, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdIn(List<Long> values) {
|
||||
addCriterion("question_id in", values, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdNotIn(List<Long> values) {
|
||||
addCriterion("question_id not in", values, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdBetween(Long value1, Long value2) {
|
||||
addCriterion("question_id between", value1, value2, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQuestionIdNotBetween(Long value1, Long value2) {
|
||||
addCriterion("question_id not between", value1, value2, "questionId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdIsNull() {
|
||||
addCriterion("agent_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdIsNotNull() {
|
||||
addCriterion("agent_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdEqualTo(Integer value) {
|
||||
addCriterion("agent_id =", value, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdNotEqualTo(Integer value) {
|
||||
addCriterion("agent_id <>", value, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdGreaterThan(Integer value) {
|
||||
addCriterion("agent_id >", value, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdGreaterThanOrEqualTo(Integer value) {
|
||||
addCriterion("agent_id >=", value, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdLessThan(Integer value) {
|
||||
addCriterion("agent_id <", value, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdLessThanOrEqualTo(Integer value) {
|
||||
addCriterion("agent_id <=", value, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdIn(List<Integer> values) {
|
||||
addCriterion("agent_id in", values, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdNotIn(List<Integer> values) {
|
||||
addCriterion("agent_id not in", values, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdBetween(Integer value1, Integer value2) {
|
||||
addCriterion("agent_id between", value1, value2, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andAgentIdNotBetween(Integer value1, Integer value2) {
|
||||
addCriterion("agent_id not between", value1, value2, "agentId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNull() {
|
||||
addCriterion("create_time is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNotNull() {
|
||||
addCriterion("create_time is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeEqualTo(Date value) {
|
||||
addCriterion("create_time =", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeNotEqualTo(Date value) {
|
||||
addCriterion("create_time <>", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeGreaterThan(Date value) {
|
||||
addCriterion("create_time >", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeGreaterThanOrEqualTo(Date value) {
|
||||
addCriterion("create_time >=", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeLessThan(Date value) {
|
||||
addCriterion("create_time <", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeLessThanOrEqualTo(Date value) {
|
||||
addCriterion("create_time <=", value, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIn(List<Date> values) {
|
||||
addCriterion("create_time in", values, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeNotIn(List<Date> values) {
|
||||
addCriterion("create_time not in", values, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeBetween(Date value1, Date value2) {
|
||||
addCriterion("create_time between", value1, value2, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeNotBetween(Date value1, Date value2) {
|
||||
addCriterion("create_time not between", value1, value2, "createTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameIsNull() {
|
||||
addCriterion("user_name is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameIsNotNull() {
|
||||
addCriterion("user_name is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameEqualTo(String value) {
|
||||
addCriterion("user_name =", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameNotEqualTo(String value) {
|
||||
addCriterion("user_name <>", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameGreaterThan(String value) {
|
||||
addCriterion("user_name >", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("user_name >=", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameLessThan(String value) {
|
||||
addCriterion("user_name <", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameLessThanOrEqualTo(String value) {
|
||||
addCriterion("user_name <=", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameLike(String value) {
|
||||
addCriterion("user_name like", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameNotLike(String value) {
|
||||
addCriterion("user_name not like", value, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameIn(List<String> values) {
|
||||
addCriterion("user_name in", values, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameNotIn(List<String> values) {
|
||||
addCriterion("user_name not in", values, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameBetween(String value1, String value2) {
|
||||
addCriterion("user_name between", value1, value2, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUserNameNotBetween(String value1, String value2) {
|
||||
addCriterion("user_name not between", value1, value2, "userName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateIsNull() {
|
||||
addCriterion("query_state is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateIsNotNull() {
|
||||
addCriterion("query_state is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateEqualTo(Integer value) {
|
||||
addCriterion("query_state =", value, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateNotEqualTo(Integer value) {
|
||||
addCriterion("query_state <>", value, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateGreaterThan(Integer value) {
|
||||
addCriterion("query_state >", value, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateGreaterThanOrEqualTo(Integer value) {
|
||||
addCriterion("query_state >=", value, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateLessThan(Integer value) {
|
||||
addCriterion("query_state <", value, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateLessThanOrEqualTo(Integer value) {
|
||||
addCriterion("query_state <=", value, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateIn(List<Integer> values) {
|
||||
addCriterion("query_state in", values, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateNotIn(List<Integer> values) {
|
||||
addCriterion("query_state not in", values, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateBetween(Integer value1, Integer value2) {
|
||||
addCriterion("query_state between", value1, value2, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andQueryStateNotBetween(Integer value1, Integer value2) {
|
||||
addCriterion("query_state not between", value1, value2, "queryState");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdIsNull() {
|
||||
addCriterion("chat_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdIsNotNull() {
|
||||
addCriterion("chat_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdEqualTo(Long value) {
|
||||
addCriterion("chat_id =", value, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdNotEqualTo(Long value) {
|
||||
addCriterion("chat_id <>", value, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdGreaterThan(Long value) {
|
||||
addCriterion("chat_id >", value, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("chat_id >=", value, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdLessThan(Long value) {
|
||||
addCriterion("chat_id <", value, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdLessThanOrEqualTo(Long value) {
|
||||
addCriterion("chat_id <=", value, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdIn(List<Long> values) {
|
||||
addCriterion("chat_id in", values, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdNotIn(List<Long> values) {
|
||||
addCriterion("chat_id not in", values, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdBetween(Long value1, Long value2) {
|
||||
addCriterion("chat_id between", value1, value2, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andChatIdNotBetween(Long value1, Long value2) {
|
||||
addCriterion("chat_id not between", value1, value2, "chatId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreIsNull() {
|
||||
addCriterion("score is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreIsNotNull() {
|
||||
addCriterion("score is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreEqualTo(Integer value) {
|
||||
addCriterion("score =", value, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreNotEqualTo(Integer value) {
|
||||
addCriterion("score <>", value, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreGreaterThan(Integer value) {
|
||||
addCriterion("score >", value, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreGreaterThanOrEqualTo(Integer value) {
|
||||
addCriterion("score >=", value, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreLessThan(Integer value) {
|
||||
addCriterion("score <", value, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreLessThanOrEqualTo(Integer value) {
|
||||
addCriterion("score <=", value, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreIn(List<Integer> values) {
|
||||
addCriterion("score in", values, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreNotIn(List<Integer> values) {
|
||||
addCriterion("score not in", values, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreBetween(Integer value1, Integer value2) {
|
||||
addCriterion("score between", value1, value2, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andScoreNotBetween(Integer value1, Integer value2) {
|
||||
addCriterion("score not between", value1, value2, "score");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackIsNull() {
|
||||
addCriterion("feedback is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackIsNotNull() {
|
||||
addCriterion("feedback is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackEqualTo(String value) {
|
||||
addCriterion("feedback =", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackNotEqualTo(String value) {
|
||||
addCriterion("feedback <>", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackGreaterThan(String value) {
|
||||
addCriterion("feedback >", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("feedback >=", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackLessThan(String value) {
|
||||
addCriterion("feedback <", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackLessThanOrEqualTo(String value) {
|
||||
addCriterion("feedback <=", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackLike(String value) {
|
||||
addCriterion("feedback like", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackNotLike(String value) {
|
||||
addCriterion("feedback not like", value, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackIn(List<String> values) {
|
||||
addCriterion("feedback in", values, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackNotIn(List<String> values) {
|
||||
addCriterion("feedback not in", values, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackBetween(String value1, String value2) {
|
||||
addCriterion("feedback between", value1, value2, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFeedbackNotBetween(String value1, String value2) {
|
||||
addCriterion("feedback not between", value1, value2, "feedback");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s2_chat_query
|
||||
*/
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
||||
protected Criteria() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s2_chat_query null
|
||||
*/
|
||||
public static class Criterion {
|
||||
private String condition;
|
||||
|
||||
private Object value;
|
||||
|
||||
private Object secondValue;
|
||||
|
||||
private boolean noValue;
|
||||
|
||||
private boolean singleValue;
|
||||
|
||||
private boolean betweenValue;
|
||||
|
||||
private boolean listValue;
|
||||
|
||||
private String typeHandler;
|
||||
|
||||
protected Criterion(String condition) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.typeHandler = null;
|
||||
this.noValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.typeHandler = typeHandler;
|
||||
if (value instanceof List<?>) {
|
||||
this.listValue = true;
|
||||
} else {
|
||||
this.singleValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value) {
|
||||
this(condition, value, null);
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.secondValue = secondValue;
|
||||
this.typeHandler = typeHandler;
|
||||
this.betweenValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue) {
|
||||
this(condition, value, secondValue, null);
|
||||
}
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object getSecondValue() {
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
public boolean isNoValue() {
|
||||
return noValue;
|
||||
}
|
||||
|
||||
public boolean isSingleValue() {
|
||||
return singleValue;
|
||||
}
|
||||
|
||||
public boolean isBetweenValue() {
|
||||
return betweenValue;
|
||||
}
|
||||
|
||||
public boolean isListValue() {
|
||||
return listValue;
|
||||
}
|
||||
|
||||
public String getTypeHandler() {
|
||||
return typeHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
public enum CostType {
|
||||
MAPPER(1, "mapper"),
|
||||
PARSER(2, "parser"),
|
||||
QUERY(3, "query"),
|
||||
PROCESSOR(4, "processor");
|
||||
|
||||
private Integer type;
|
||||
private String name;
|
||||
|
||||
CostType(Integer type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DictConfDO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private Long modelId;
|
||||
|
||||
private String dimValueInfos;
|
||||
|
||||
private String createdBy;
|
||||
private String updatedBy;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class DictTaskDO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private String command;
|
||||
|
||||
private String commandMd5;
|
||||
|
||||
private String dimIds;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String createdBy;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private Double progress;
|
||||
|
||||
private Long elapsedMs;
|
||||
|
||||
public String getCommandMd5() {
|
||||
return DigestUtils.md5Hex(command);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.core.config.DefaultMetric;
|
||||
import com.tencent.supersonic.chat.core.config.Dim4Dict;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class DimValueDO {
|
||||
|
||||
private Long modelId;
|
||||
|
||||
private List<DefaultMetric> defaultMetricDescList = new ArrayList<>();
|
||||
|
||||
private List<Dim4Dict> dimensions = new ArrayList<>();
|
||||
|
||||
public DimValueDO setModelId(Long modelId) {
|
||||
this.modelId = modelId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DimValueDO setDefaultMetricIds(List<DefaultMetric> defaultMetricDescList) {
|
||||
this.defaultMetricDescList = defaultMetricDescList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DimValueDO setDimensions(List<Dim4Dict> dimensions) {
|
||||
this.dimensions = dimensions;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class PluginDO {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* DASHBOARD,WIDGET,URL
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String model;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String parseMode;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Date createdAt;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Date updatedAt;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String updatedBy;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String parseModeConfig;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String config;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String comment;
|
||||
|
||||
/**
|
||||
* @return id
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* DASHBOARD,WIDGET,URL
|
||||
*
|
||||
* @return type DASHBOARD,WIDGET,URL
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* DASHBOARD,WIDGET,URL
|
||||
*
|
||||
* @param type DASHBOARD,WIDGET,URL
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type == null ? null : type.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return model
|
||||
*/
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param model
|
||||
*/
|
||||
public void setModel(String model) {
|
||||
this.model = model == null ? null : model.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pattern
|
||||
*/
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pattern
|
||||
*/
|
||||
public void setPattern(String pattern) {
|
||||
this.pattern = pattern == null ? null : pattern.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return parse_mode
|
||||
*/
|
||||
public String getParseMode() {
|
||||
return parseMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parseMode
|
||||
*/
|
||||
public void setParseMode(String parseMode) {
|
||||
this.parseMode = parseMode == null ? null : parseMode.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name == null ? null : name.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return created_at
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param createdAt
|
||||
*/
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return created_by
|
||||
*/
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param createdBy
|
||||
*/
|
||||
public void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy == null ? null : createdBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return updated_at
|
||||
*/
|
||||
public Date getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param updatedAt
|
||||
*/
|
||||
public void setUpdatedAt(Date updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return updated_by
|
||||
*/
|
||||
public String getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param updatedBy
|
||||
*/
|
||||
public void setUpdatedBy(String updatedBy) {
|
||||
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return parse_mode_config
|
||||
*/
|
||||
public String getParseModeConfig() {
|
||||
return parseModeConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parseModeConfig
|
||||
*/
|
||||
public void setParseModeConfig(String parseModeConfig) {
|
||||
this.parseModeConfig = parseModeConfig == null ? null : parseModeConfig.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return config
|
||||
*/
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param config
|
||||
*/
|
||||
public void setConfig(String config) {
|
||||
this.config = config == null ? null : config.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return comment
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param comment
|
||||
*/
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment == null ? null : comment.trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,960 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class PluginDOExample {
|
||||
/**
|
||||
* s2_plugin
|
||||
*/
|
||||
protected String orderByClause;
|
||||
|
||||
/**
|
||||
* s2_plugin
|
||||
*/
|
||||
protected boolean distinct;
|
||||
|
||||
/**
|
||||
* s2_plugin
|
||||
*/
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
/**
|
||||
* s2_plugin
|
||||
*/
|
||||
protected Integer limitStart;
|
||||
|
||||
/**
|
||||
* s2_plugin
|
||||
*/
|
||||
protected Integer limitEnd;
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public PluginDOExample() {
|
||||
oredCriteria = new ArrayList<Criteria>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setOrderByClause(String orderByClause) {
|
||||
this.orderByClause = orderByClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public String getOrderByClause() {
|
||||
return orderByClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setDistinct(boolean distinct) {
|
||||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public boolean isDistinct() {
|
||||
return distinct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public List<Criteria> getOredCriteria() {
|
||||
return oredCriteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void or(Criteria criteria) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Criteria or() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
oredCriteria.add(criteria);
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Criteria createCriteria() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
if (oredCriteria.size() == 0) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
protected Criteria createCriteriaInternal() {
|
||||
Criteria criteria = new Criteria();
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void clear() {
|
||||
oredCriteria.clear();
|
||||
orderByClause = null;
|
||||
distinct = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setLimitStart(Integer limitStart) {
|
||||
this.limitStart = limitStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Integer getLimitStart() {
|
||||
return limitStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public void setLimitEnd(Integer limitEnd) {
|
||||
this.limitEnd = limitEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @mbg.generated
|
||||
*/
|
||||
public Integer getLimitEnd() {
|
||||
return limitEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* s2_plugin null
|
||||
*/
|
||||
protected abstract static class GeneratedCriteria {
|
||||
protected List<Criterion> criteria;
|
||||
|
||||
protected GeneratedCriteria() {
|
||||
super();
|
||||
criteria = new ArrayList<Criterion>();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return criteria.size() > 0;
|
||||
}
|
||||
|
||||
public List<Criterion> getAllCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public List<Criterion> getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition) {
|
||||
if (condition == null) {
|
||||
throw new RuntimeException("Value for condition cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value, String property) {
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||
if (value1 == null || value2 == null) {
|
||||
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value1, value2));
|
||||
}
|
||||
|
||||
public Criteria andIdIsNull() {
|
||||
addCriterion("id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdIsNotNull() {
|
||||
addCriterion("id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdEqualTo(Long value) {
|
||||
addCriterion("id =", value, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdNotEqualTo(Long value) {
|
||||
addCriterion("id <>", value, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdGreaterThan(Long value) {
|
||||
addCriterion("id >", value, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("id >=", value, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdLessThan(Long value) {
|
||||
addCriterion("id <", value, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdLessThanOrEqualTo(Long value) {
|
||||
addCriterion("id <=", value, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdIn(List<Long> values) {
|
||||
addCriterion("id in", values, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdNotIn(List<Long> values) {
|
||||
addCriterion("id not in", values, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdBetween(Long value1, Long value2) {
|
||||
addCriterion("id between", value1, value2, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andIdNotBetween(Long value1, Long value2) {
|
||||
addCriterion("id not between", value1, value2, "id");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeIsNull() {
|
||||
addCriterion("type is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeIsNotNull() {
|
||||
addCriterion("type is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeEqualTo(String value) {
|
||||
addCriterion("type =", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeNotEqualTo(String value) {
|
||||
addCriterion("type <>", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeGreaterThan(String value) {
|
||||
addCriterion("type >", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("type >=", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeLessThan(String value) {
|
||||
addCriterion("type <", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeLessThanOrEqualTo(String value) {
|
||||
addCriterion("type <=", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeLike(String value) {
|
||||
addCriterion("type like", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeNotLike(String value) {
|
||||
addCriterion("type not like", value, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeIn(List<String> values) {
|
||||
addCriterion("type in", values, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeNotIn(List<String> values) {
|
||||
addCriterion("type not in", values, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeBetween(String value1, String value2) {
|
||||
addCriterion("type between", value1, value2, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTypeNotBetween(String value1, String value2) {
|
||||
addCriterion("type not between", value1, value2, "type");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelIsNull() {
|
||||
addCriterion("model is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelIsNotNull() {
|
||||
addCriterion("model is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelEqualTo(String value) {
|
||||
addCriterion("model =", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelNotEqualTo(String value) {
|
||||
addCriterion("model <>", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelGreaterThan(String value) {
|
||||
addCriterion("model >", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("model >=", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelLessThan(String value) {
|
||||
addCriterion("model <", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelLessThanOrEqualTo(String value) {
|
||||
addCriterion("model <=", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelLike(String value) {
|
||||
addCriterion("model like", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelNotLike(String value) {
|
||||
addCriterion("model not like", value, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelIn(List<String> values) {
|
||||
addCriterion("model in", values, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelNotIn(List<String> values) {
|
||||
addCriterion("model not in", values, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelBetween(String value1, String value2) {
|
||||
addCriterion("model between", value1, value2, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelNotBetween(String value1, String value2) {
|
||||
addCriterion("model not between", value1, value2, "model");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternIsNull() {
|
||||
addCriterion("pattern is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternIsNotNull() {
|
||||
addCriterion("pattern is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternEqualTo(String value) {
|
||||
addCriterion("pattern =", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternNotEqualTo(String value) {
|
||||
addCriterion("pattern <>", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternGreaterThan(String value) {
|
||||
addCriterion("pattern >", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("pattern >=", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternLessThan(String value) {
|
||||
addCriterion("pattern <", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternLessThanOrEqualTo(String value) {
|
||||
addCriterion("pattern <=", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternLike(String value) {
|
||||
addCriterion("pattern like", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternNotLike(String value) {
|
||||
addCriterion("pattern not like", value, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternIn(List<String> values) {
|
||||
addCriterion("pattern in", values, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternNotIn(List<String> values) {
|
||||
addCriterion("pattern not in", values, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternBetween(String value1, String value2) {
|
||||
addCriterion("pattern between", value1, value2, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPatternNotBetween(String value1, String value2) {
|
||||
addCriterion("pattern not between", value1, value2, "pattern");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeIsNull() {
|
||||
addCriterion("parse_mode is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeIsNotNull() {
|
||||
addCriterion("parse_mode is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeEqualTo(String value) {
|
||||
addCriterion("parse_mode =", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeNotEqualTo(String value) {
|
||||
addCriterion("parse_mode <>", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeGreaterThan(String value) {
|
||||
addCriterion("parse_mode >", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("parse_mode >=", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeLessThan(String value) {
|
||||
addCriterion("parse_mode <", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeLessThanOrEqualTo(String value) {
|
||||
addCriterion("parse_mode <=", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeLike(String value) {
|
||||
addCriterion("parse_mode like", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeNotLike(String value) {
|
||||
addCriterion("parse_mode not like", value, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeIn(List<String> values) {
|
||||
addCriterion("parse_mode in", values, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeNotIn(List<String> values) {
|
||||
addCriterion("parse_mode not in", values, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeBetween(String value1, String value2) {
|
||||
addCriterion("parse_mode between", value1, value2, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andParseModeNotBetween(String value1, String value2) {
|
||||
addCriterion("parse_mode not between", value1, value2, "parseMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameIsNull() {
|
||||
addCriterion("name is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameIsNotNull() {
|
||||
addCriterion("name is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameEqualTo(String value) {
|
||||
addCriterion("name =", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameNotEqualTo(String value) {
|
||||
addCriterion("name <>", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameGreaterThan(String value) {
|
||||
addCriterion("name >", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("name >=", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameLessThan(String value) {
|
||||
addCriterion("name <", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameLessThanOrEqualTo(String value) {
|
||||
addCriterion("name <=", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameLike(String value) {
|
||||
addCriterion("name like", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameNotLike(String value) {
|
||||
addCriterion("name not like", value, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameIn(List<String> values) {
|
||||
addCriterion("name in", values, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameNotIn(List<String> values) {
|
||||
addCriterion("name not in", values, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameBetween(String value1, String value2) {
|
||||
addCriterion("name between", value1, value2, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNameNotBetween(String value1, String value2) {
|
||||
addCriterion("name not between", value1, value2, "name");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtIsNull() {
|
||||
addCriterion("created_at is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtIsNotNull() {
|
||||
addCriterion("created_at is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtEqualTo(Date value) {
|
||||
addCriterion("created_at =", value, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtNotEqualTo(Date value) {
|
||||
addCriterion("created_at <>", value, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtGreaterThan(Date value) {
|
||||
addCriterion("created_at >", value, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtGreaterThanOrEqualTo(Date value) {
|
||||
addCriterion("created_at >=", value, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtLessThan(Date value) {
|
||||
addCriterion("created_at <", value, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtLessThanOrEqualTo(Date value) {
|
||||
addCriterion("created_at <=", value, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtIn(List<Date> values) {
|
||||
addCriterion("created_at in", values, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtNotIn(List<Date> values) {
|
||||
addCriterion("created_at not in", values, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtBetween(Date value1, Date value2) {
|
||||
addCriterion("created_at between", value1, value2, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedAtNotBetween(Date value1, Date value2) {
|
||||
addCriterion("created_at not between", value1, value2, "createdAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByIsNull() {
|
||||
addCriterion("created_by is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByIsNotNull() {
|
||||
addCriterion("created_by is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByEqualTo(String value) {
|
||||
addCriterion("created_by =", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByNotEqualTo(String value) {
|
||||
addCriterion("created_by <>", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByGreaterThan(String value) {
|
||||
addCriterion("created_by >", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("created_by >=", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByLessThan(String value) {
|
||||
addCriterion("created_by <", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByLessThanOrEqualTo(String value) {
|
||||
addCriterion("created_by <=", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByLike(String value) {
|
||||
addCriterion("created_by like", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByNotLike(String value) {
|
||||
addCriterion("created_by not like", value, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByIn(List<String> values) {
|
||||
addCriterion("created_by in", values, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByNotIn(List<String> values) {
|
||||
addCriterion("created_by not in", values, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByBetween(String value1, String value2) {
|
||||
addCriterion("created_by between", value1, value2, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreatedByNotBetween(String value1, String value2) {
|
||||
addCriterion("created_by not between", value1, value2, "createdBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtIsNull() {
|
||||
addCriterion("updated_at is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtIsNotNull() {
|
||||
addCriterion("updated_at is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtEqualTo(Date value) {
|
||||
addCriterion("updated_at =", value, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtNotEqualTo(Date value) {
|
||||
addCriterion("updated_at <>", value, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtGreaterThan(Date value) {
|
||||
addCriterion("updated_at >", value, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtGreaterThanOrEqualTo(Date value) {
|
||||
addCriterion("updated_at >=", value, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtLessThan(Date value) {
|
||||
addCriterion("updated_at <", value, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtLessThanOrEqualTo(Date value) {
|
||||
addCriterion("updated_at <=", value, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtIn(List<Date> values) {
|
||||
addCriterion("updated_at in", values, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtNotIn(List<Date> values) {
|
||||
addCriterion("updated_at not in", values, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtBetween(Date value1, Date value2) {
|
||||
addCriterion("updated_at between", value1, value2, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedAtNotBetween(Date value1, Date value2) {
|
||||
addCriterion("updated_at not between", value1, value2, "updatedAt");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByIsNull() {
|
||||
addCriterion("updated_by is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByIsNotNull() {
|
||||
addCriterion("updated_by is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByEqualTo(String value) {
|
||||
addCriterion("updated_by =", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByNotEqualTo(String value) {
|
||||
addCriterion("updated_by <>", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByGreaterThan(String value) {
|
||||
addCriterion("updated_by >", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("updated_by >=", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByLessThan(String value) {
|
||||
addCriterion("updated_by <", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByLessThanOrEqualTo(String value) {
|
||||
addCriterion("updated_by <=", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByLike(String value) {
|
||||
addCriterion("updated_by like", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByNotLike(String value) {
|
||||
addCriterion("updated_by not like", value, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByIn(List<String> values) {
|
||||
addCriterion("updated_by in", values, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByNotIn(List<String> values) {
|
||||
addCriterion("updated_by not in", values, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByBetween(String value1, String value2) {
|
||||
addCriterion("updated_by between", value1, value2, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andUpdatedByNotBetween(String value1, String value2) {
|
||||
addCriterion("updated_by not between", value1, value2, "updatedBy");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s2_plugin
|
||||
*/
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
||||
protected Criteria() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s2_plugin null
|
||||
*/
|
||||
public static class Criterion {
|
||||
private String condition;
|
||||
|
||||
private Object value;
|
||||
|
||||
private Object secondValue;
|
||||
|
||||
private boolean noValue;
|
||||
|
||||
private boolean singleValue;
|
||||
|
||||
private boolean betweenValue;
|
||||
|
||||
private boolean listValue;
|
||||
|
||||
private String typeHandler;
|
||||
|
||||
protected Criterion(String condition) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.typeHandler = null;
|
||||
this.noValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.typeHandler = typeHandler;
|
||||
if (value instanceof List<?>) {
|
||||
this.listValue = true;
|
||||
} else {
|
||||
this.singleValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value) {
|
||||
this(condition, value, null);
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.secondValue = secondValue;
|
||||
this.typeHandler = typeHandler;
|
||||
this.betweenValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue) {
|
||||
this(condition, value, secondValue, null);
|
||||
}
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object getSecondValue() {
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
public boolean isNoValue() {
|
||||
return noValue;
|
||||
}
|
||||
|
||||
public boolean isSingleValue() {
|
||||
return singleValue;
|
||||
}
|
||||
|
||||
public boolean isBetweenValue() {
|
||||
return betweenValue;
|
||||
}
|
||||
|
||||
public boolean isListValue() {
|
||||
return listValue;
|
||||
}
|
||||
|
||||
public String getTypeHandler() {
|
||||
return typeHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class QueryDO {
|
||||
|
||||
public String aggregator = "trend";
|
||||
public String startTime;
|
||||
public String endTime;
|
||||
private long id;
|
||||
private long questionId;
|
||||
private String createTime;
|
||||
private String time;
|
||||
private String userName;
|
||||
private String question;
|
||||
private Object queryResults;
|
||||
private int state;
|
||||
private String dataContent;
|
||||
private String name;
|
||||
private int queryType;
|
||||
private int isDeleted;
|
||||
private String module;
|
||||
private long chatId;
|
||||
private int topNum;
|
||||
private String querySql;
|
||||
private Object queryColumn;
|
||||
private Object entityInfo;
|
||||
private int score;
|
||||
private String feedback;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.dataobject;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class StatisticsDO {
|
||||
/**
|
||||
* questionId
|
||||
*/
|
||||
private Long questionId;
|
||||
|
||||
/**
|
||||
* chatId
|
||||
*/
|
||||
private Long chatId;
|
||||
|
||||
/**
|
||||
* createTime
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* queryText
|
||||
*/
|
||||
private String queryText;
|
||||
|
||||
/**
|
||||
* userName
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
|
||||
/**
|
||||
* interface
|
||||
*/
|
||||
private String interfaceName;
|
||||
|
||||
/**
|
||||
* cost
|
||||
*/
|
||||
private Integer cost;
|
||||
|
||||
private Integer type;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDOExample;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface AgentDOMapper {
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
long countByExample(AgentDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int deleteByPrimaryKey(Integer id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insert(AgentDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insertSelective(AgentDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
List<AgentDO> selectByExample(AgentDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
AgentDO selectByPrimaryKey(Integer id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByExampleSelective(@Param("record") AgentDO record, @Param("example") AgentDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByExample(@Param("record") AgentDO record, @Param("example") AgentDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKeySelective(AgentDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKey(AgentDO record);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfigFilterInternal;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface ChatConfigMapper {
|
||||
|
||||
Long addConfig(ChatConfigDO chaConfigPO);
|
||||
|
||||
Long editConfig(ChatConfigDO chaConfigPO);
|
||||
|
||||
List<ChatConfigDO> search(ChatConfigFilterInternal filterInternal);
|
||||
|
||||
ChatConfigDO fetchConfigByModelId(Long modelId);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatContextDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface ChatContextMapper {
|
||||
|
||||
ChatContextDO getContextByChatId(int chatId);
|
||||
|
||||
int updateContext(ChatContextDO contextDO);
|
||||
|
||||
int addContext(ChatContextDO contextDO);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.QueryDO;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface ChatMapper {
|
||||
|
||||
boolean createChat(ChatDO chatDO);
|
||||
|
||||
List<ChatDO> getAll(String creator, Integer agentId);
|
||||
|
||||
Boolean updateChatName(Long chatId, String chatName, String lastTime, String creator);
|
||||
|
||||
Boolean updateLastQuestion(Long chatId, String lastQuestion, String lastTime);
|
||||
|
||||
Boolean updateConversionIsTop(Long chatId, int isTop);
|
||||
|
||||
boolean updateFeedback(QueryDO queryDO);
|
||||
|
||||
Boolean deleteChat(Long chatId, String userName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface ChatParseMapper {
|
||||
|
||||
boolean batchSaveParseInfo(@Param("list") List<ChatParseDO> list);
|
||||
|
||||
boolean updateParseInfo(ChatParseDO chatParseDO);
|
||||
|
||||
ChatParseDO getParseInfo(Long questionId, int parseId);
|
||||
|
||||
List<ChatParseDO> getParseInfoList(List<Long> questionIds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDOExample;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ChatQueryDOMapper {
|
||||
|
||||
int insert(ChatQueryDO record);
|
||||
|
||||
List<ChatQueryDO> selectByExampleWithBLOBs(ChatQueryDOExample example);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(ChatQueryDO record);
|
||||
|
||||
Boolean deleteByPrimaryKey(Long questionId);
|
||||
|
||||
ChatQueryDO selectByPrimaryKey(Long questionId);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictConfDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface DictConfMapper {
|
||||
|
||||
Boolean createDictConf(DictConfDO dictConfDO);
|
||||
|
||||
Boolean editDictConf(DictConfDO dictConfDO);
|
||||
|
||||
Boolean upsertDictInfo(DictConfDO dictConfDO);
|
||||
|
||||
DictConfDO getDictInfoByModelId(Long modelId);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictTaskDO;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictTaskFilterReq;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface DictTaskMapper {
|
||||
|
||||
Long createDimValueTask(DictTaskDO dictTaskDO);
|
||||
|
||||
Boolean updateTaskStatus(DictTaskDO dictTaskDO);
|
||||
|
||||
List<DictTaskDO> searchDictTaskList(DictTaskFilterReq filter);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDOExample;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface PluginDOMapper {
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
long countByExample(PluginDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int deleteByPrimaryKey(Long id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insert(PluginDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insertSelective(PluginDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
List<PluginDO> selectByExampleWithBLOBs(PluginDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
List<PluginDO> selectByExample(PluginDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
PluginDO selectByPrimaryKey(Long id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKeySelective(PluginDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKeyWithBLOBs(PluginDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKey(PluginDO record);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.StatisticsDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface StatisticsMapper {
|
||||
boolean batchSaveStatistics(@Param("list") List<StatisticsDO> list);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.mapper.custom;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ShowCaseCustomMapper {
|
||||
|
||||
List<ChatQueryDO> queryShowCase(int start, int limit, int agentId, String userName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AgentRepository {
|
||||
|
||||
List<AgentDO> getAgents();
|
||||
|
||||
void createAgent(AgentDO agentDO);
|
||||
|
||||
void updateAgent(AgentDO agentDO);
|
||||
|
||||
AgentDO getAgent(Integer id);
|
||||
|
||||
void deleteAgent(Integer id);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfig;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ChatConfigRepository {
|
||||
|
||||
Long createConfig(ChatConfig chaConfig);
|
||||
|
||||
Long updateConfig(ChatConfig chaConfig);
|
||||
|
||||
List<ChatConfigResp> getChatConfig(ChatConfigFilter filter);
|
||||
|
||||
ChatConfigResp getConfigByModelId(Long modelId);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
|
||||
public interface ChatContextRepository {
|
||||
|
||||
ChatContext getOrCreateContext(int chatId);
|
||||
|
||||
void updateContext(ChatContext chatCtx);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ChatQueryRepository {
|
||||
|
||||
PageInfo<QueryResp> getChatQuery(PageQueryInfoReq pageQueryInfoCommend, Long chatId);
|
||||
|
||||
QueryResp getChatQuery(Long queryId);
|
||||
|
||||
ChatQueryDO getChatQueryDO(Long queryId);
|
||||
|
||||
List<QueryResp> queryShowCase(PageQueryInfoReq pageQueryInfoCommend, int agentId);
|
||||
|
||||
void updateChatParseInfo(List<ChatParseDO> chatParseDOS);
|
||||
|
||||
ChatQueryDO getLastChatQuery(long chatId);
|
||||
|
||||
int updateChatQuery(ChatQueryDO chatQueryDO);
|
||||
|
||||
List<ChatParseDO> batchSaveParseInfo(ChatContext chatCtx, QueryReq queryReq,
|
||||
ParseResp parseResult,
|
||||
List<SemanticParseInfo> candidateParses);
|
||||
|
||||
ChatParseDO getParseInfo(Long questionId, int parseId);
|
||||
|
||||
List<ChatParseDO> getParseInfoList(List<Long> questionIds);
|
||||
|
||||
Boolean deleteChatQuery(Long questionId);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.QueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
|
||||
import java.util.List;
|
||||
|
||||
public interface ChatRepository {
|
||||
|
||||
boolean createChat(ChatDO chatDO);
|
||||
|
||||
List<ChatDO> getAll(String creator, Integer agentId);
|
||||
|
||||
Boolean updateChatName(Long chatId, String chatName, String lastTime, String creator);
|
||||
|
||||
Boolean updateLastQuestion(Long chatId, String lastQuestion, String lastTime);
|
||||
|
||||
Boolean updateConversionIsTop(Long chatId, int isTop);
|
||||
|
||||
boolean updateFeedback(QueryDO queryDO);
|
||||
|
||||
Boolean deleteChat(Long chatId, String userName);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictTaskFilterReq;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictConfig;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValueDictInfo;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictTaskDO;
|
||||
import java.util.List;
|
||||
|
||||
public interface DictRepository {
|
||||
|
||||
Long createDimValueDictTask(DictTaskDO dictTaskDO);
|
||||
|
||||
Boolean updateDictTaskStatus(Integer status, DictTaskDO dictTaskDO);
|
||||
|
||||
List<DimValueDictInfo> searchDictTaskList(DictTaskFilterReq filter);
|
||||
|
||||
DictConfig getDictInfoByModelId(Long modelId);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDOExample;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PluginRepository {
|
||||
List<PluginDO> getPlugins();
|
||||
|
||||
List<PluginDO> fetchPluginDOs(String queryText, String type);
|
||||
|
||||
void createPlugin(PluginDO pluginDO);
|
||||
|
||||
void updatePlugin(PluginDO pluginDO);
|
||||
|
||||
PluginDO getPlugin(Long id);
|
||||
|
||||
List<PluginDO> query(PluginDOExample pluginDOExample);
|
||||
|
||||
void deletePlugin(Long id);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository;
|
||||
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.StatisticsDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StatisticsRepository {
|
||||
|
||||
void batchSaveStatistics(List<StatisticsDO> list);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDOExample;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.AgentDOMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.AgentRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class AgentRepositoryImpl implements AgentRepository {
|
||||
|
||||
private AgentDOMapper agentDOMapper;
|
||||
|
||||
public AgentRepositoryImpl(AgentDOMapper agentDOMapper) {
|
||||
this.agentDOMapper = agentDOMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AgentDO> getAgents() {
|
||||
return agentDOMapper.selectByExample(new AgentDOExample());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAgent(AgentDO agentDO) {
|
||||
agentDOMapper.insert(agentDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAgent(AgentDO agentDO) {
|
||||
agentDOMapper.updateByPrimaryKey(agentDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentDO getAgent(Integer id) {
|
||||
return agentDOMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAgent(Integer id) {
|
||||
agentDOMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfig;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfigFilterInternal;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.ChatConfigMapper;
|
||||
import com.tencent.supersonic.chat.server.util.ChatConfigHelper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatConfigRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Repository
|
||||
@Primary
|
||||
public class ChatConfigRepositoryImpl implements ChatConfigRepository {
|
||||
|
||||
private final ChatConfigHelper chatConfigHelper;
|
||||
private final ChatConfigMapper chatConfigMapper;
|
||||
|
||||
public ChatConfigRepositoryImpl(ChatConfigHelper chatConfigHelper,
|
||||
ChatConfigMapper chatConfigMapper) {
|
||||
this.chatConfigHelper = chatConfigHelper;
|
||||
this.chatConfigMapper = chatConfigMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createConfig(ChatConfig chaConfig) {
|
||||
ChatConfigDO chaConfigDO = chatConfigHelper.chatConfig2DO(chaConfig);
|
||||
chatConfigMapper.addConfig(chaConfigDO);
|
||||
return chaConfigDO.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long updateConfig(ChatConfig chaConfig) {
|
||||
ChatConfigDO chaConfigDO = chatConfigHelper.chatConfig2DO(chaConfig);
|
||||
|
||||
return chatConfigMapper.editConfig(chaConfigDO);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
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(chatConfigHelper
|
||||
.chatConfigDO2Descriptor(chaConfigDO.getModelId(), chaConfigDO)));
|
||||
}
|
||||
return chaConfigDescriptorList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatConfigResp getConfigByModelId(Long modelId) {
|
||||
ChatConfigDO chaConfigPO = chatConfigMapper.fetchConfigByModelId(modelId);
|
||||
return chatConfigHelper.chatConfigDO2Descriptor(modelId, chaConfigPO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatContextDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.ChatContextMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatContextRepository;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@Primary
|
||||
@Slf4j
|
||||
public class ChatContextRepositoryImpl implements ChatContextRepository {
|
||||
|
||||
@Autowired(required = false)
|
||||
private final ChatContextMapper chatContextMapper;
|
||||
|
||||
public ChatContextRepositoryImpl(ChatContextMapper chatContextMapper) {
|
||||
this.chatContextMapper = chatContextMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatContext getOrCreateContext(int chatId) {
|
||||
ChatContextDO context = chatContextMapper.getContextByChatId(chatId);
|
||||
if (context == null) {
|
||||
ChatContext chatContext = new ChatContext();
|
||||
chatContext.setChatId(chatId);
|
||||
return chatContext;
|
||||
}
|
||||
return cast(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContext(ChatContext chatCtx) {
|
||||
ChatContextDO context = cast(chatCtx);
|
||||
if (chatContextMapper.getContextByChatId(chatCtx.getChatId()) == null) {
|
||||
chatContextMapper.addContext(context);
|
||||
} else {
|
||||
chatContextMapper.updateContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
private ChatContext cast(ChatContextDO contextDO) {
|
||||
ChatContext chatContext = new ChatContext();
|
||||
chatContext.setChatId(contextDO.getChatId());
|
||||
chatContext.setUser(contextDO.getUser());
|
||||
chatContext.setQueryText(contextDO.getQueryText());
|
||||
if (contextDO.getSemanticParse() != null && !contextDO.getSemanticParse().isEmpty()) {
|
||||
log.info("--->: {}", contextDO.getSemanticParse());
|
||||
SemanticParseInfo semanticParseInfo = JsonUtil.toObject(contextDO.getSemanticParse(),
|
||||
SemanticParseInfo.class);
|
||||
chatContext.setParseInfo(semanticParseInfo);
|
||||
}
|
||||
return chatContext;
|
||||
}
|
||||
|
||||
private ChatContextDO cast(ChatContext chatContext) {
|
||||
ChatContextDO chatContextDO = new ChatContextDO();
|
||||
chatContextDO.setChatId(chatContext.getChatId());
|
||||
chatContextDO.setQueryText(chatContext.getQueryText());
|
||||
chatContextDO.setUser(chatContext.getUser());
|
||||
if (chatContext.getParseInfo() != null) {
|
||||
Gson g = new Gson();
|
||||
chatContextDO.setSemanticParse(g.toJson(chatContext.getParseInfo()));
|
||||
}
|
||||
return chatContextDO;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SimilarQueryRecallResp;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.custom.ShowCaseCustomMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDOExample;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDOExample.Criteria;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.ChatParseMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.ChatQueryDOMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatQueryRepository;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.common.util.PageUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Repository
|
||||
@Primary
|
||||
@Slf4j
|
||||
public class ChatQueryRepositoryImpl implements ChatQueryRepository {
|
||||
|
||||
private final ChatQueryDOMapper chatQueryDOMapper;
|
||||
|
||||
private final ChatParseMapper chatParseMapper;
|
||||
|
||||
private final ShowCaseCustomMapper showCaseCustomMapper;
|
||||
|
||||
public ChatQueryRepositoryImpl(ChatQueryDOMapper chatQueryDOMapper,
|
||||
ChatParseMapper chatParseMapper,
|
||||
ShowCaseCustomMapper showCaseCustomMapper) {
|
||||
this.chatQueryDOMapper = chatQueryDOMapper;
|
||||
this.chatParseMapper = chatParseMapper;
|
||||
this.showCaseCustomMapper = showCaseCustomMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<QueryResp> getChatQuery(PageQueryInfoReq pageQueryInfoReq, Long chatId) {
|
||||
ChatQueryDOExample example = new ChatQueryDOExample();
|
||||
example.setOrderByClause("question_id desc");
|
||||
Criteria criteria = example.createCriteria();
|
||||
if (chatId != null) {
|
||||
criteria.andChatIdEqualTo(chatId);
|
||||
}
|
||||
if (StringUtils.isNotBlank(pageQueryInfoReq.getUserName())) {
|
||||
criteria.andUserNameEqualTo(pageQueryInfoReq.getUserName());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(pageQueryInfoReq.getIds())) {
|
||||
criteria.andQuestionIdIn(pageQueryInfoReq.getIds());
|
||||
}
|
||||
PageInfo<ChatQueryDO> pageInfo = PageHelper.startPage(pageQueryInfoReq.getCurrent(),
|
||||
pageQueryInfoReq.getPageSize())
|
||||
.doSelectPageInfo(() -> chatQueryDOMapper.selectByExampleWithBLOBs(example));
|
||||
|
||||
PageInfo<QueryResp> chatQueryVOPageInfo = PageUtils.pageInfo2PageInfoVo(pageInfo);
|
||||
chatQueryVOPageInfo.setList(
|
||||
pageInfo.getList().stream().filter(o -> !StringUtils.isEmpty(o.getQueryResult())).map(this::convertTo)
|
||||
.sorted(Comparator.comparingInt(o -> o.getQuestionId().intValue()))
|
||||
.collect(Collectors.toList()));
|
||||
return chatQueryVOPageInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResp getChatQuery(Long queryId) {
|
||||
ChatQueryDO chatQueryDO = getChatQueryDO(queryId);
|
||||
if (Objects.isNull(chatQueryDO)) {
|
||||
return new QueryResp();
|
||||
}
|
||||
return convertTo(chatQueryDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatQueryDO getChatQueryDO(Long queryId) {
|
||||
return chatQueryDOMapper.selectByPrimaryKey(queryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QueryResp> queryShowCase(PageQueryInfoReq pageQueryInfoReq, int agentId) {
|
||||
return showCaseCustomMapper.queryShowCase(pageQueryInfoReq.getLimitStart(),
|
||||
pageQueryInfoReq.getPageSize(), agentId, pageQueryInfoReq.getUserName())
|
||||
.stream().map(this::convertTo)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private QueryResp convertTo(ChatQueryDO chatQueryDO) {
|
||||
QueryResp queryResp = new QueryResp();
|
||||
BeanUtils.copyProperties(chatQueryDO, queryResp);
|
||||
QueryResult queryResult = JsonUtil.toObject(chatQueryDO.getQueryResult(), QueryResult.class);
|
||||
if (queryResult != null) {
|
||||
queryResult.setQueryId(chatQueryDO.getQuestionId());
|
||||
queryResp.setQueryResult(queryResult);
|
||||
}
|
||||
if (StringUtils.isNotBlank(chatQueryDO.getSimilarQueries())) {
|
||||
List<SimilarQueryRecallResp> similarQueries = JSONObject.parseArray(chatQueryDO.getSimilarQueries(),
|
||||
SimilarQueryRecallResp.class);
|
||||
queryResp.setSimilarQueries(similarQueries);
|
||||
}
|
||||
return queryResp;
|
||||
}
|
||||
|
||||
public Long createChatQuery(ParseResp parseResult, ChatContext chatCtx, QueryReq queryReq) {
|
||||
ChatQueryDO chatQueryDO = new ChatQueryDO();
|
||||
chatQueryDO.setChatId(Long.valueOf(chatCtx.getChatId()));
|
||||
chatQueryDO.setCreateTime(new java.util.Date());
|
||||
chatQueryDO.setUserName(queryReq.getUser().getName());
|
||||
chatQueryDO.setQueryText(queryReq.getQueryText());
|
||||
chatQueryDO.setAgentId(queryReq.getAgentId());
|
||||
chatQueryDO.setQueryResult("");
|
||||
try {
|
||||
chatQueryDOMapper.insert(chatQueryDO);
|
||||
} catch (Exception e) {
|
||||
log.info("database insert has an exception:{}", e.toString());
|
||||
}
|
||||
Long queryId = chatQueryDO.getQuestionId();
|
||||
parseResult.setQueryId(queryId);
|
||||
return queryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatParseDO> batchSaveParseInfo(ChatContext chatCtx, QueryReq queryReq,
|
||||
ParseResp parseResult, List<SemanticParseInfo> candidateParses) {
|
||||
Long queryId = createChatQuery(parseResult, chatCtx, queryReq);
|
||||
List<ChatParseDO> chatParseDOList = new ArrayList<>();
|
||||
getChatParseDO(chatCtx, queryReq, queryId, candidateParses, chatParseDOList);
|
||||
if (!CollectionUtils.isEmpty(candidateParses)) {
|
||||
chatParseMapper.batchSaveParseInfo(chatParseDOList);
|
||||
}
|
||||
return chatParseDOList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateChatParseInfo(List<ChatParseDO> chatParseDOS) {
|
||||
for (ChatParseDO chatParseDO : chatParseDOS) {
|
||||
chatParseMapper.updateParseInfo(chatParseDO);
|
||||
}
|
||||
}
|
||||
|
||||
public void getChatParseDO(ChatContext chatCtx, QueryReq queryReq, Long queryId,
|
||||
List<SemanticParseInfo> parses, List<ChatParseDO> chatParseDOList) {
|
||||
for (int i = 0; i < parses.size(); i++) {
|
||||
ChatParseDO chatParseDO = new ChatParseDO();
|
||||
chatParseDO.setChatId(Long.valueOf(chatCtx.getChatId()));
|
||||
chatParseDO.setQuestionId(queryId);
|
||||
chatParseDO.setQueryText(queryReq.getQueryText());
|
||||
chatParseDO.setParseInfo(JsonUtil.toString(parses.get(i)));
|
||||
chatParseDO.setIsCandidate(1);
|
||||
if (i == 0) {
|
||||
chatParseDO.setIsCandidate(0);
|
||||
}
|
||||
chatParseDO.setParseId(parses.get(i).getId());
|
||||
chatParseDO.setCreateTime(new java.util.Date());
|
||||
chatParseDO.setUserName(queryReq.getUser().getName());
|
||||
chatParseDOList.add(chatParseDO);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatQueryDO getLastChatQuery(long chatId) {
|
||||
ChatQueryDOExample example = new ChatQueryDOExample();
|
||||
example.setOrderByClause("question_id desc");
|
||||
example.setLimitEnd(1);
|
||||
example.setLimitStart(0);
|
||||
Criteria criteria = example.createCriteria();
|
||||
criteria.andChatIdEqualTo(chatId);
|
||||
List<ChatQueryDO> chatQueryDOS = chatQueryDOMapper.selectByExampleWithBLOBs(example);
|
||||
if (!CollectionUtils.isEmpty(chatQueryDOS)) {
|
||||
return chatQueryDOS.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateChatQuery(ChatQueryDO chatQueryDO) {
|
||||
return chatQueryDOMapper.updateByPrimaryKeyWithBLOBs(chatQueryDO);
|
||||
}
|
||||
|
||||
public ChatParseDO getParseInfo(Long questionId, int parseId) {
|
||||
return chatParseMapper.getParseInfo(questionId, parseId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatParseDO> getParseInfoList(List<Long> questionIds) {
|
||||
return chatParseMapper.getParseInfoList(questionIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteChatQuery(Long questionId) {
|
||||
return chatQueryDOMapper.deleteByPrimaryKey(questionId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.QueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.ChatMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatRepository;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@Primary
|
||||
@Slf4j
|
||||
public class ChatRepositoryImpl implements ChatRepository {
|
||||
|
||||
private final ChatMapper chatMapper;
|
||||
|
||||
public ChatRepositoryImpl(ChatMapper chatMapper) {
|
||||
this.chatMapper = chatMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createChat(ChatDO chatDO) {
|
||||
return chatMapper.createChat(chatDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatDO> getAll(String creator, Integer agentId) {
|
||||
return chatMapper.getAll(creator, agentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateChatName(Long chatId, String chatName, String lastTime, String creator) {
|
||||
return chatMapper.updateChatName(chatId, chatName, lastTime, creator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateLastQuestion(Long chatId, String lastQuestion, String lastTime) {
|
||||
return chatMapper.updateLastQuestion(chatId, lastQuestion, lastTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateConversionIsTop(Long chatId, int isTop) {
|
||||
return chatMapper.updateConversionIsTop(chatId, isTop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateFeedback(QueryDO queryDO) {
|
||||
return chatMapper.updateFeedback(queryDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteChat(Long chatId, String userName) {
|
||||
return chatMapper.deleteChat(chatId, userName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictTaskFilterReq;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictConfig;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValueDictInfo;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictConfDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictTaskDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.DictConfMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.DictTaskMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.DictRepository;
|
||||
import com.tencent.supersonic.chat.server.util.DictTaskConverter;
|
||||
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Repository
|
||||
@Slf4j
|
||||
public class DictRepositoryImpl implements DictRepository {
|
||||
|
||||
private final DictTaskMapper dictTaskMapper;
|
||||
private final DictConfMapper dictConfMapper;
|
||||
|
||||
public DictRepositoryImpl(DictTaskMapper dictTaskMapper,
|
||||
DictConfMapper dictConfMapper) {
|
||||
this.dictTaskMapper = dictTaskMapper;
|
||||
this.dictConfMapper = dictConfMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createDimValueDictTask(DictTaskDO dictTaskDO) {
|
||||
dictTaskMapper.createDimValueTask(dictTaskDO);
|
||||
return dictTaskDO.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateDictTaskStatus(Integer status, DictTaskDO dictTaskDO) {
|
||||
dictTaskDO.setStatus(status);
|
||||
Date createdAt = dictTaskDO.getCreatedAt();
|
||||
long elapsedMs = System.currentTimeMillis() - createdAt.getTime();
|
||||
dictTaskDO.setElapsedMs(elapsedMs);
|
||||
dictTaskMapper.updateTaskStatus(dictTaskDO);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DimValueDictInfo> searchDictTaskList(DictTaskFilterReq filter) {
|
||||
List<DimValueDictInfo> dimValueDictDescList = new ArrayList<>();
|
||||
log.info("filter:{}", filter);
|
||||
List<DictTaskDO> dictTaskDOList = dictTaskMapper.searchDictTaskList(filter);
|
||||
if (!CollectionUtils.isEmpty(dictTaskDOList)) {
|
||||
dictTaskDOList.stream().forEach(dictTaskDO -> {
|
||||
DimValueDictInfo dimValueDictDesc = new DimValueDictInfo();
|
||||
BeanUtils.copyProperties(dictTaskDO, dimValueDictDesc);
|
||||
dimValueDictDesc.setStatus(TaskStatusEnum.of(dictTaskDO.getStatus()));
|
||||
if (StringUtils.isNotEmpty(dictTaskDO.getDimIds())) {
|
||||
Set<Long> dimIds = JsonUtil.toSet(dictTaskDO.getDimIds(), Long.class);
|
||||
dimValueDictDesc.setDimIds(dimIds);
|
||||
}
|
||||
dimValueDictDescList.add(dimValueDictDesc);
|
||||
});
|
||||
}
|
||||
return dimValueDictDescList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictConfig getDictInfoByModelId(Long modelId) {
|
||||
DictConfDO dictConfDO = dictConfMapper.getDictInfoByModelId(modelId);
|
||||
if (Objects.isNull(dictConfDO)) {
|
||||
return null;
|
||||
}
|
||||
return DictTaskConverter.dictConfPO2Config(dictConfDO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDOExample;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.PluginDOMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.PluginRepository;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Repository
|
||||
@Slf4j
|
||||
public class PluginRepositoryImpl implements PluginRepository {
|
||||
|
||||
private PluginDOMapper pluginDOMapper;
|
||||
|
||||
public PluginRepositoryImpl(PluginDOMapper pluginDOMapper) {
|
||||
this.pluginDOMapper = pluginDOMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PluginDO> getPlugins() {
|
||||
return pluginDOMapper.selectByExampleWithBLOBs(new PluginDOExample());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PluginDO> fetchPluginDOs(String queryText, String type) {
|
||||
|
||||
List<PluginDO> pluginDOList = new ArrayList<>();
|
||||
|
||||
PluginRepository pluginRepository = ContextUtils.getBean(PluginRepository.class);
|
||||
List<PluginDO> pluginDOS = pluginRepository.getPlugins();
|
||||
|
||||
for (PluginDO pluginDO : pluginDOS) {
|
||||
String pattern = pluginDO.getPattern();
|
||||
if (Strings.isNotEmpty(pattern)) {
|
||||
|
||||
Pattern pluginPattern = Pattern.compile(pattern);
|
||||
Matcher pluginMatcher = pluginPattern.matcher(queryText);
|
||||
if (pluginMatcher.find()) {
|
||||
log.info("pluginMatcher.find() is true, queryText:{}", queryText);
|
||||
log.info("pluginDO:{}", pluginDO);
|
||||
pluginDOList.add(pluginDO);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pluginDOList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPlugin(PluginDO pluginDO) {
|
||||
pluginDOMapper.insert(pluginDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePlugin(PluginDO pluginDO) {
|
||||
pluginDOMapper.updateByPrimaryKeyWithBLOBs(pluginDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginDO getPlugin(Long id) {
|
||||
return pluginDOMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PluginDO> query(PluginDOExample pluginDOExample) {
|
||||
return pluginDOMapper.selectByExampleWithBLOBs(pluginDOExample);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePlugin(Long id) {
|
||||
pluginDOMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.tencent.supersonic.chat.server.persistence.repository.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.StatisticsDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.mapper.StatisticsMapper;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.StatisticsRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
@Primary
|
||||
@Slf4j
|
||||
public class StatisticsRepositoryImpl implements StatisticsRepository {
|
||||
|
||||
private final StatisticsMapper statisticsMapper;
|
||||
|
||||
public StatisticsRepositoryImpl(StatisticsMapper statisticsMapper) {
|
||||
this.statisticsMapper = statisticsMapper;
|
||||
}
|
||||
|
||||
public void batchSaveStatistics(List<StatisticsDO> list) {
|
||||
statisticsMapper.batchSaveStatistics(list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.tencent.supersonic.chat.server.processor;
|
||||
|
||||
/**
|
||||
* A ResultProcessor wraps things up before returning results to users.
|
||||
*/
|
||||
public interface ResultProcessor {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.tencent.supersonic.chat.server.processor.execute;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.RelatedSchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.server.service.SemanticService;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* DimensionRecommendProcessor recommend some dimensions
|
||||
* related to metrics based on configuration
|
||||
*/
|
||||
public class DimensionRecommendProcessor implements ExecuteResultProcessor {
|
||||
|
||||
private static final int recommend_dimension_size = 5;
|
||||
|
||||
@Override
|
||||
public void process(QueryResult queryResult, SemanticParseInfo semanticParseInfo, ExecuteQueryReq queryReq) {
|
||||
if (!QueryType.METRIC.equals(semanticParseInfo.getQueryType())
|
||||
|| CollectionUtils.isEmpty(semanticParseInfo.getMetrics())) {
|
||||
return;
|
||||
}
|
||||
SchemaElement element = semanticParseInfo.getMetrics().iterator().next();
|
||||
List<SchemaElement> dimensionRecommended = getDimensions(element.getId(), element.getModel());
|
||||
queryResult.setRecommendedDimensions(dimensionRecommended);
|
||||
}
|
||||
|
||||
private List<SchemaElement> getDimensions(Long metricId, Long modelId) {
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
ModelSchema modelSchema = semanticService.getModelSchema(modelId);
|
||||
List<Long> drillDownDimensions = Lists.newArrayList();
|
||||
Set<SchemaElement> metricElements = modelSchema.getMetrics();
|
||||
if (!CollectionUtils.isEmpty(metricElements)) {
|
||||
Optional<SchemaElement> metric = metricElements.stream().filter(schemaElement ->
|
||||
metricId.equals(schemaElement.getId())
|
||||
&& !CollectionUtils.isEmpty(schemaElement.getRelatedSchemaElements()))
|
||||
.findFirst();
|
||||
if (metric.isPresent()) {
|
||||
drillDownDimensions = metric.get().getRelatedSchemaElements().stream()
|
||||
.map(RelatedSchemaElement::getDimensionId).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
final List<Long> drillDownDimensionsFinal = drillDownDimensions;
|
||||
return modelSchema.getDimensions().stream()
|
||||
.filter(dim -> filterDimension(drillDownDimensionsFinal, dim))
|
||||
.sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed())
|
||||
.limit(recommend_dimension_size)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean filterDimension(List<Long> drillDownDimensions, SchemaElement dimension) {
|
||||
if (Objects.isNull(dimension)) {
|
||||
return false;
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(drillDownDimensions)) {
|
||||
return drillDownDimensions.contains(dimension.getId());
|
||||
}
|
||||
return Objects.nonNull(dimension.getUseCnt());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.tencent.supersonic.chat.server.processor.execute;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.server.processor.ResultProcessor;
|
||||
|
||||
/**
|
||||
* A ExecuteResultProcessor wraps things up before returning results to users in execute stage.
|
||||
*/
|
||||
public interface ExecuteResultProcessor extends ResultProcessor {
|
||||
|
||||
void process(QueryResult queryResult, SemanticParseInfo semanticParseInfo, ExecuteQueryReq queryReq);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.tencent.supersonic.chat.server.processor.execute;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.common.config.EmbeddingConfig;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.util.ComponentFactory;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.embedding.Retrieval;
|
||||
import com.tencent.supersonic.common.util.embedding.RetrieveQuery;
|
||||
import com.tencent.supersonic.common.util.embedding.RetrieveQueryResult;
|
||||
import com.tencent.supersonic.common.util.embedding.S2EmbeddingStore;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* MetricRecommendProcessor fills recommended metrics based on embedding similarity.
|
||||
*/
|
||||
public class MetricRecommendProcessor implements ExecuteResultProcessor {
|
||||
|
||||
private static final int METRIC_RECOMMEND_SIZE = 5;
|
||||
|
||||
private S2EmbeddingStore s2EmbeddingStore = ComponentFactory.getS2EmbeddingStore();
|
||||
|
||||
@Override
|
||||
public void process(QueryResult queryResult, SemanticParseInfo semanticParseInfo, ExecuteQueryReq queryReq) {
|
||||
fillSimilarMetric(queryResult.getChatContext());
|
||||
}
|
||||
|
||||
private void fillSimilarMetric(SemanticParseInfo parseInfo) {
|
||||
if (!parseInfo.getQueryType().equals(QueryType.METRIC)
|
||||
|| parseInfo.getMetrics().size() > METRIC_RECOMMEND_SIZE
|
||||
|| CollectionUtils.isEmpty(parseInfo.getMetrics())) {
|
||||
return;
|
||||
}
|
||||
List<String> metricNames = Collections.singletonList(parseInfo.getMetrics().iterator().next().getName());
|
||||
Map<String, String> filterCondition = new HashMap<>();
|
||||
filterCondition.put("modelId", parseInfo.getMetrics().iterator().next().getModel().toString());
|
||||
filterCondition.put("type", SchemaElementType.METRIC.name());
|
||||
RetrieveQuery retrieveQuery = RetrieveQuery.builder().queryTextsList(metricNames)
|
||||
.filterCondition(filterCondition).queryEmbeddings(null).build();
|
||||
|
||||
EmbeddingConfig embeddingConfig = ContextUtils.getBean(EmbeddingConfig.class);
|
||||
|
||||
List<RetrieveQueryResult> retrieveQueryResults = s2EmbeddingStore.retrieveQuery(
|
||||
embeddingConfig.getMetaCollectionName(), retrieveQuery, METRIC_RECOMMEND_SIZE + 1);
|
||||
if (CollectionUtils.isEmpty(retrieveQueryResults)) {
|
||||
return;
|
||||
}
|
||||
List<Retrieval> retrievals = retrieveQueryResults.stream()
|
||||
.flatMap(retrieveQueryResult -> retrieveQueryResult.getRetrieval().stream())
|
||||
.sorted(Comparator.comparingDouble(Retrieval::getDistance))
|
||||
.distinct().collect(Collectors.toList());
|
||||
Set<Long> metricIds = parseInfo.getMetrics().stream().map(SchemaElement::getId).collect(Collectors.toSet());
|
||||
int metricOrder = 0;
|
||||
for (SchemaElement metric : parseInfo.getMetrics()) {
|
||||
metric.setOrder(metricOrder++);
|
||||
}
|
||||
for (Retrieval retrieval : retrievals) {
|
||||
if (!metricIds.contains(Retrieval.getLongId(retrieval.getId()))) {
|
||||
SchemaElement schemaElement = JSONObject.parseObject(JSONObject.toJSONString(retrieval.getMetadata()),
|
||||
SchemaElement.class);
|
||||
if (retrieval.getMetadata().containsKey("modelId")) {
|
||||
String modelId = retrieval.getMetadata().get("modelId").toString();
|
||||
schemaElement.setModel(Long.parseLong(modelId));
|
||||
}
|
||||
schemaElement.setOrder(++metricOrder);
|
||||
parseInfo.getMetrics().add(schemaElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.core.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.core.query.llm.analytics.MetricAnalyzeQuery;
|
||||
import com.tencent.supersonic.chat.server.service.SemanticService;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* EntityInfoProcessor fills core attributes of an entity so that
|
||||
* users get to know which entity is parsed out.
|
||||
*/
|
||||
public class EntityInfoProcessor implements ParseResultProcessor {
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
List<SemanticQuery> semanticQueries = queryContext.getCandidateQueries();
|
||||
if (CollectionUtils.isEmpty(semanticQueries)) {
|
||||
return;
|
||||
}
|
||||
List<SemanticParseInfo> selectedParses = semanticQueries.stream().map(SemanticQuery::getParseInfo)
|
||||
.collect(Collectors.toList());
|
||||
QueryReq queryReq = queryContext.getRequest();
|
||||
selectedParses.forEach(parseInfo -> {
|
||||
String queryMode = parseInfo.getQueryMode();
|
||||
if (QueryManager.containsPluginQuery(queryMode)
|
||||
|| MetricAnalyzeQuery.QUERY_MODE.equalsIgnoreCase(queryMode)) {
|
||||
return;
|
||||
}
|
||||
//1. set entity info
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
EntityInfo entityInfo = semanticService.getEntityInfo(parseInfo, queryReq.getUser());
|
||||
if (QueryManager.isTagQuery(queryMode)
|
||||
|| QueryManager.isMetricQuery(queryMode)) {
|
||||
parseInfo.setEntityInfo(entityInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.RelatedSchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.server.service.SemanticService;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserRemoveHelper;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* MetricCheckProcessor verifies whether the dimensions
|
||||
* involved in the query in metric mode can drill down on the metric.
|
||||
*/
|
||||
@Slf4j
|
||||
public class MetricCheckProcessor implements ParseResultProcessor {
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
List<SemanticQuery> semanticQueries = queryContext.getCandidateQueries();
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
SemanticSchema semanticSchema = semanticService.getSemanticSchema();
|
||||
for (SemanticQuery semanticQuery : semanticQueries) {
|
||||
SemanticParseInfo parseInfo = semanticQuery.getParseInfo();
|
||||
if (!QueryType.METRIC.equals(parseInfo.getQueryType())) {
|
||||
continue;
|
||||
}
|
||||
String correctSqlProcessed = processCorrectSql(parseInfo, semanticSchema);
|
||||
log.info("correct sql:{}", correctSqlProcessed);
|
||||
parseInfo.getSqlInfo().setCorrectS2SQL(correctSqlProcessed);
|
||||
}
|
||||
semanticQueries.removeIf(semanticQuery -> {
|
||||
if (!QueryType.METRIC.equals(semanticQuery.getParseInfo().getQueryType())) {
|
||||
return false;
|
||||
}
|
||||
String correctSql = semanticQuery.getParseInfo().getSqlInfo().getCorrectS2SQL();
|
||||
if (StringUtils.isBlank(correctSql)) {
|
||||
return false;
|
||||
}
|
||||
return !checkHasMetric(correctSql, semanticSchema);
|
||||
});
|
||||
}
|
||||
|
||||
public String processCorrectSql(SemanticParseInfo parseInfo, SemanticSchema semanticSchema) {
|
||||
String correctSql = parseInfo.getSqlInfo().getCorrectS2SQL();
|
||||
List<String> groupByFields = SqlParserSelectHelper.getGroupByFields(correctSql);
|
||||
List<String> metricFields = SqlParserSelectHelper.getAggregateFields(correctSql);
|
||||
List<String> whereFields = SqlParserSelectHelper.getWhereFields(correctSql);
|
||||
List<String> dimensionFields = getDimensionFields(groupByFields, whereFields);
|
||||
if (CollectionUtils.isEmpty(metricFields) || StringUtils.isBlank(correctSql)) {
|
||||
return correctSql;
|
||||
}
|
||||
Set<String> metricToRemove = Sets.newHashSet();
|
||||
Set<String> groupByToRemove = Sets.newHashSet();
|
||||
Set<String> whereFieldsToRemove = Sets.newHashSet();
|
||||
for (String metricName : metricFields) {
|
||||
SchemaElement metricElement = semanticSchema.getElementByName(SchemaElementType.METRIC, metricName);
|
||||
if (metricElement == null) {
|
||||
metricToRemove.add(metricName);
|
||||
}
|
||||
if (!checkNecessaryDimension(metricElement, semanticSchema, dimensionFields)) {
|
||||
metricToRemove.add(metricName);
|
||||
}
|
||||
}
|
||||
for (String dimensionName : whereFields) {
|
||||
if (TimeDimensionEnum.containsTimeDimension(dimensionName)) {
|
||||
continue;
|
||||
}
|
||||
if (!checkInModelSchema(dimensionName, SchemaElementType.DIMENSION, semanticSchema)) {
|
||||
whereFieldsToRemove.add(dimensionName);
|
||||
}
|
||||
if (!checkDrillDownDimension(dimensionName, metricFields, semanticSchema)) {
|
||||
whereFieldsToRemove.add(dimensionName);
|
||||
}
|
||||
}
|
||||
for (String dimensionName : groupByFields) {
|
||||
if (TimeDimensionEnum.containsTimeDimension(dimensionName)) {
|
||||
continue;
|
||||
}
|
||||
if (!checkInModelSchema(dimensionName, SchemaElementType.DIMENSION, semanticSchema)) {
|
||||
groupByToRemove.add(dimensionName);
|
||||
}
|
||||
if (!checkDrillDownDimension(dimensionName, metricFields, semanticSchema)) {
|
||||
groupByToRemove.add(dimensionName);
|
||||
}
|
||||
}
|
||||
return removeFieldInSql(correctSql, metricToRemove, groupByToRemove, whereFieldsToRemove);
|
||||
}
|
||||
|
||||
/**
|
||||
* To check whether the dimension bound to the metric exists,
|
||||
* eg: metric like UV is calculated in a certain dimension, it cannot be used on other dimensions.
|
||||
*/
|
||||
private boolean checkNecessaryDimension(SchemaElement metric, SemanticSchema semanticSchema,
|
||||
List<String> dimensionFields) {
|
||||
List<String> necessaryDimensions = getNecessaryDimensionNames(metric, semanticSchema);
|
||||
if (CollectionUtils.isEmpty(necessaryDimensions)) {
|
||||
return true;
|
||||
}
|
||||
for (String dimension : necessaryDimensions) {
|
||||
if (!dimensionFields.contains(dimension)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* To check whether the dimension can drill down the metric,
|
||||
* eg: some descriptive dimensions are not suitable as drill-down dimensions
|
||||
*/
|
||||
private boolean checkDrillDownDimension(String dimensionName, List<String> metrics,
|
||||
SemanticSchema semanticSchema) {
|
||||
List<SchemaElement> metricElements = semanticSchema.getMetrics().stream()
|
||||
.filter(schemaElement -> metrics.contains(schemaElement.getName()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(metricElements)) {
|
||||
return false;
|
||||
}
|
||||
List<String> relateDimensions = metricElements.stream()
|
||||
.filter(schemaElement -> !CollectionUtils.isEmpty(schemaElement.getRelatedSchemaElements()))
|
||||
.map(schemaElement -> schemaElement.getRelatedSchemaElements().stream()
|
||||
.map(RelatedSchemaElement::getDimensionId).collect(Collectors.toList()))
|
||||
.flatMap(Collection::stream)
|
||||
.map(id -> convertDimensionIdToName(id, semanticSchema))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
//if no metric has drill down dimension, return true
|
||||
if (CollectionUtils.isEmpty(relateDimensions)) {
|
||||
return true;
|
||||
}
|
||||
//if this dimension not in relate drill-down dimensions, return false
|
||||
return relateDimensions.contains(dimensionName);
|
||||
}
|
||||
|
||||
private List<String> getNecessaryDimensionNames(SchemaElement metric, SemanticSchema semanticSchema) {
|
||||
List<Long> necessaryDimensionIds = getNecessaryDimensions(metric);
|
||||
return necessaryDimensionIds.stream().map(id -> convertDimensionIdToName(id, semanticSchema))
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Long> getNecessaryDimensions(SchemaElement metric) {
|
||||
if (metric == null) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
List<RelatedSchemaElement> relateSchemaElements = metric.getRelatedSchemaElements();
|
||||
if (CollectionUtils.isEmpty(relateSchemaElements)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return relateSchemaElements.stream()
|
||||
.filter(RelatedSchemaElement::isNecessary).map(RelatedSchemaElement::getDimensionId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> getDimensionFields(List<String> groupByFields, List<String> whereFields) {
|
||||
List<String> dimensionFields = Lists.newArrayList();
|
||||
if (!CollectionUtils.isEmpty(groupByFields)) {
|
||||
dimensionFields.addAll(groupByFields);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(whereFields)) {
|
||||
dimensionFields.addAll(whereFields);
|
||||
}
|
||||
return dimensionFields;
|
||||
}
|
||||
|
||||
private String convertDimensionIdToName(Long id, SemanticSchema semanticSchema) {
|
||||
SchemaElement schemaElement = semanticSchema.getElement(SchemaElementType.DIMENSION, id);
|
||||
if (schemaElement == null) {
|
||||
return null;
|
||||
}
|
||||
return schemaElement.getName();
|
||||
}
|
||||
|
||||
private boolean checkInModelSchema(String name, SchemaElementType type, SemanticSchema semanticSchema) {
|
||||
SchemaElement schemaElement = semanticSchema.getElementByName(type, name);
|
||||
return schemaElement != null;
|
||||
}
|
||||
|
||||
private boolean checkHasMetric(String correctSql, SemanticSchema semanticSchema) {
|
||||
List<String> selectFields = SqlParserSelectHelper.getSelectFields(correctSql);
|
||||
List<String> aggFields = SqlParserSelectHelper.getAggregateFields(correctSql);
|
||||
List<String> collect = semanticSchema.getMetrics().stream()
|
||||
.map(SchemaElement::getName).collect(Collectors.toList());
|
||||
for (String field : selectFields) {
|
||||
if (collect.contains(field)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !CollectionUtils.isEmpty(aggFields);
|
||||
}
|
||||
|
||||
private static String removeFieldInSql(String sql, Set<String> metricToRemove,
|
||||
Set<String> dimensionByToRemove, Set<String> whereFieldsToRemove) {
|
||||
sql = SqlParserRemoveHelper.removeWhereCondition(sql, whereFieldsToRemove);
|
||||
sql = SqlParserRemoveHelper.removeSelect(sql, metricToRemove);
|
||||
sql = SqlParserRemoveHelper.removeSelect(sql, dimensionByToRemove);
|
||||
sql = SqlParserRemoveHelper.removeGroupBy(sql, dimensionByToRemove);
|
||||
sql = SqlParserRemoveHelper.removeNumberFilter(sql);
|
||||
return sql;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SqlInfo;
|
||||
import com.tencent.supersonic.chat.server.service.impl.SchemaService;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.FieldExpression;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* ParseInfoProcessor extracts structured info from S2SQL so that
|
||||
* users get to know the details.
|
||||
**/
|
||||
@Slf4j
|
||||
public class ParseInfoProcessor implements ParseResultProcessor {
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
List<SemanticQuery> candidateQueries = queryContext.getCandidateQueries();
|
||||
if (CollectionUtils.isEmpty(candidateQueries)) {
|
||||
return;
|
||||
}
|
||||
List<SemanticParseInfo> candidateParses = candidateQueries.stream()
|
||||
.map(SemanticQuery::getParseInfo).collect(Collectors.toList());
|
||||
candidateParses.forEach(this::updateParseInfo);
|
||||
}
|
||||
|
||||
public void updateParseInfo(SemanticParseInfo parseInfo) {
|
||||
SqlInfo sqlInfo = parseInfo.getSqlInfo();
|
||||
String correctS2SQL = sqlInfo.getCorrectS2SQL();
|
||||
if (StringUtils.isBlank(correctS2SQL)) {
|
||||
return;
|
||||
}
|
||||
// if S2SQL equals correctS2SQL, then not update the parseInfo.
|
||||
if (correctS2SQL.equals(sqlInfo.getS2SQL())) {
|
||||
return;
|
||||
}
|
||||
List<FieldExpression> expressions = SqlParserSelectHelper.getFilterExpression(correctS2SQL);
|
||||
//set dataInfo
|
||||
try {
|
||||
if (!org.apache.commons.collections.CollectionUtils.isEmpty(expressions)) {
|
||||
DateConf dateInfo = getDateInfo(expressions);
|
||||
if (dateInfo != null && parseInfo.getDateInfo() == null) {
|
||||
parseInfo.setDateInfo(dateInfo);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("set dateInfo error :", e);
|
||||
}
|
||||
|
||||
//set filter
|
||||
Set<Long> modelIds = parseInfo.getModel().getModelIds();
|
||||
try {
|
||||
Map<String, SchemaElement> fieldNameToElement = getNameToElement(modelIds);
|
||||
List<QueryFilter> result = getDimensionFilter(fieldNameToElement, expressions);
|
||||
parseInfo.getDimensionFilters().addAll(result);
|
||||
} catch (Exception e) {
|
||||
log.error("set dimensionFilter error :", e);
|
||||
}
|
||||
|
||||
SemanticSchema semanticSchema = ContextUtils.getBean(SchemaService.class).getSemanticSchema();
|
||||
if (Objects.isNull(semanticSchema)) {
|
||||
return;
|
||||
}
|
||||
List<String> allFields = getFieldsExceptDate(SqlParserSelectHelper.getAllFields(sqlInfo.getCorrectS2SQL()));
|
||||
Set<SchemaElement> metrics = getElements(modelIds, allFields, semanticSchema.getMetrics());
|
||||
parseInfo.setMetrics(metrics);
|
||||
if (QueryType.METRIC.equals(parseInfo.getQueryType())) {
|
||||
List<String> groupByFields = SqlParserSelectHelper.getGroupByFields(sqlInfo.getCorrectS2SQL());
|
||||
List<String> groupByDimensions = getFieldsExceptDate(groupByFields);
|
||||
parseInfo.setDimensions(getElements(modelIds, groupByDimensions, semanticSchema.getDimensions()));
|
||||
} else if (QueryType.TAG.equals(parseInfo.getQueryType())) {
|
||||
List<String> selectFields = SqlParserSelectHelper.getSelectFields(sqlInfo.getCorrectS2SQL());
|
||||
List<String> selectDimensions = getFieldsExceptDate(selectFields);
|
||||
parseInfo.setDimensions(getElements(modelIds, selectDimensions, semanticSchema.getDimensions()));
|
||||
}
|
||||
}
|
||||
|
||||
private Set<SchemaElement> getElements(Set<Long> modelIds, List<String> allFields, List<SchemaElement> elements) {
|
||||
return elements.stream()
|
||||
.filter(schemaElement -> modelIds.contains(schemaElement.getModel()) && allFields.contains(
|
||||
schemaElement.getName())
|
||||
).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private List<String> getFieldsExceptDate(List<String> allFields) {
|
||||
if (org.springframework.util.CollectionUtils.isEmpty(allFields)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return allFields.stream()
|
||||
.filter(entry -> !TimeDimensionEnum.DAY.getChName().equalsIgnoreCase(entry))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<QueryFilter> getDimensionFilter(Map<String, SchemaElement> fieldNameToElement,
|
||||
List<FieldExpression> fieldExpressions) {
|
||||
List<QueryFilter> result = Lists.newArrayList();
|
||||
for (FieldExpression expression : fieldExpressions) {
|
||||
QueryFilter dimensionFilter = new QueryFilter();
|
||||
dimensionFilter.setValue(expression.getFieldValue());
|
||||
SchemaElement schemaElement = fieldNameToElement.get(expression.getFieldName());
|
||||
if (Objects.isNull(schemaElement)) {
|
||||
continue;
|
||||
}
|
||||
dimensionFilter.setName(schemaElement.getName());
|
||||
dimensionFilter.setBizName(schemaElement.getBizName());
|
||||
dimensionFilter.setElementID(schemaElement.getId());
|
||||
|
||||
FilterOperatorEnum operatorEnum = FilterOperatorEnum.getSqlOperator(expression.getOperator());
|
||||
dimensionFilter.setOperator(operatorEnum);
|
||||
dimensionFilter.setFunction(expression.getFunction());
|
||||
result.add(dimensionFilter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private DateConf getDateInfo(List<FieldExpression> fieldExpressions) {
|
||||
List<FieldExpression> dateExpressions = fieldExpressions.stream()
|
||||
.filter(expression -> TimeDimensionEnum.DAY.getChName().equalsIgnoreCase(expression.getFieldName()))
|
||||
.collect(Collectors.toList());
|
||||
if (org.apache.commons.collections.CollectionUtils.isEmpty(dateExpressions)) {
|
||||
return null;
|
||||
}
|
||||
DateConf dateInfo = new DateConf();
|
||||
dateInfo.setDateMode(DateConf.DateMode.BETWEEN);
|
||||
FieldExpression firstExpression = dateExpressions.get(0);
|
||||
|
||||
FilterOperatorEnum firstOperator = FilterOperatorEnum.getSqlOperator(firstExpression.getOperator());
|
||||
if (FilterOperatorEnum.EQUALS.equals(firstOperator) && Objects.nonNull(firstExpression.getFieldValue())) {
|
||||
dateInfo.setStartDate(firstExpression.getFieldValue().toString());
|
||||
dateInfo.setEndDate(firstExpression.getFieldValue().toString());
|
||||
dateInfo.setDateMode(DateConf.DateMode.BETWEEN);
|
||||
return dateInfo;
|
||||
}
|
||||
if (containOperators(firstExpression, firstOperator, FilterOperatorEnum.GREATER_THAN,
|
||||
FilterOperatorEnum.GREATER_THAN_EQUALS)) {
|
||||
dateInfo.setStartDate(firstExpression.getFieldValue().toString());
|
||||
if (hasSecondDate(dateExpressions)) {
|
||||
dateInfo.setEndDate(dateExpressions.get(1).getFieldValue().toString());
|
||||
}
|
||||
}
|
||||
if (containOperators(firstExpression, firstOperator, FilterOperatorEnum.MINOR_THAN,
|
||||
FilterOperatorEnum.MINOR_THAN_EQUALS)) {
|
||||
dateInfo.setEndDate(firstExpression.getFieldValue().toString());
|
||||
if (hasSecondDate(dateExpressions)) {
|
||||
dateInfo.setStartDate(dateExpressions.get(1).getFieldValue().toString());
|
||||
}
|
||||
}
|
||||
return dateInfo;
|
||||
}
|
||||
|
||||
private boolean containOperators(FieldExpression expression, FilterOperatorEnum firstOperator,
|
||||
FilterOperatorEnum... operatorEnums) {
|
||||
return (Arrays.asList(operatorEnums).contains(firstOperator) && Objects.nonNull(
|
||||
expression.getFieldValue()));
|
||||
}
|
||||
|
||||
private boolean hasSecondDate(List<FieldExpression> dateExpressions) {
|
||||
return dateExpressions.size() > 1 && Objects.nonNull(dateExpressions.get(1).getFieldValue());
|
||||
}
|
||||
|
||||
protected Map<String, SchemaElement> getNameToElement(Set<Long> modelIds) {
|
||||
SemanticSchema semanticSchema = ContextUtils.getBean(SchemaService.class).getSemanticSchema();
|
||||
List<SchemaElement> dimensions = semanticSchema.getDimensions(modelIds);
|
||||
List<SchemaElement> metrics = semanticSchema.getMetrics(modelIds);
|
||||
|
||||
List<SchemaElement> allElements = Lists.newArrayList();
|
||||
allElements.addAll(dimensions);
|
||||
allElements.addAll(metrics);
|
||||
//support alias
|
||||
return allElements.stream()
|
||||
.flatMap(schemaElement -> {
|
||||
Set<Pair<String, SchemaElement>> result = new HashSet<>();
|
||||
result.add(Pair.of(schemaElement.getName(), schemaElement));
|
||||
List<String> aliasList = schemaElement.getAlias();
|
||||
if (!org.springframework.util.CollectionUtils.isEmpty(aliasList)) {
|
||||
for (String alias : aliasList) {
|
||||
result.add(Pair.of(alias, schemaElement));
|
||||
}
|
||||
}
|
||||
return result.stream();
|
||||
})
|
||||
.collect(Collectors.toMap(pair -> pair.getLeft(), pair -> pair.getRight(),
|
||||
(value1, value2) -> value2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.server.processor.ResultProcessor;
|
||||
|
||||
/**
|
||||
* A ParseResultProcessor wraps things up before returning results to users in parse stage.
|
||||
*/
|
||||
public interface ParseResultProcessor extends ResultProcessor {
|
||||
|
||||
void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementMatch;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.core.query.rule.RuleSemanticQuery;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* QueryRankProcessor ranks candidate parsing results based on
|
||||
* a heuristic scoring algorithm and then takes topN.
|
||||
**/
|
||||
@Slf4j
|
||||
public class QueryRankProcessor implements ParseResultProcessor {
|
||||
|
||||
private static final int candidateTopSize = 5;
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
List<SemanticQuery> candidateQueries = queryContext.getCandidateQueries();
|
||||
candidateQueries = rank(candidateQueries);
|
||||
queryContext.setCandidateQueries(candidateQueries);
|
||||
}
|
||||
|
||||
public List<SemanticQuery> rank(List<SemanticQuery> candidateQueries) {
|
||||
log.debug("pick before [{}]", candidateQueries);
|
||||
if (CollectionUtils.isEmpty(candidateQueries)) {
|
||||
return candidateQueries;
|
||||
}
|
||||
List<SemanticQuery> selectedQueries = new ArrayList<>();
|
||||
if (candidateQueries.size() == 1) {
|
||||
selectedQueries.addAll(candidateQueries);
|
||||
} else {
|
||||
selectedQueries = getTopCandidateQuery(candidateQueries);
|
||||
}
|
||||
generateParseInfoId(selectedQueries);
|
||||
log.debug("pick after [{}]", selectedQueries);
|
||||
return selectedQueries;
|
||||
}
|
||||
|
||||
public List<SemanticQuery> getTopCandidateQuery(List<SemanticQuery> semanticQueries) {
|
||||
return semanticQueries.stream()
|
||||
.filter(query -> !checkFullyInherited(query))
|
||||
.sorted((o1, o2) -> {
|
||||
if (o1.getParseInfo().getScore() < o2.getParseInfo().getScore()) {
|
||||
return 1;
|
||||
} else if (o1.getParseInfo().getScore() > o2.getParseInfo().getScore()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}).limit(candidateTopSize)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void generateParseInfoId(List<SemanticQuery> semanticQueries) {
|
||||
for (int i = 0; i < semanticQueries.size(); i++) {
|
||||
SemanticQuery query = semanticQueries.get(i);
|
||||
query.getParseInfo().setId(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkFullyInherited(SemanticQuery query) {
|
||||
SemanticParseInfo parseInfo = query.getParseInfo();
|
||||
if (!(query instanceof RuleSemanticQuery)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (SchemaElementMatch match : parseInfo.getElementMatches()) {
|
||||
if (!match.isInherited()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return parseInfo.getDateInfo() == null || parseInfo.getDateInfo().isInherited();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SimilarQueryRecallResp;
|
||||
import com.tencent.supersonic.chat.core.utils.SimilarQueryManager;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatQueryRepository;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* MetricRecommendProcessor fills recommended query based on embedding similarity.
|
||||
*/
|
||||
@Slf4j
|
||||
public class QueryRecommendProcessor implements ParseResultProcessor {
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
CompletableFuture.runAsync(() -> doProcess(parseResp, queryContext));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void doProcess(ParseResp parseResp, QueryContext queryContext) {
|
||||
Long queryId = parseResp.getQueryId();
|
||||
List<SimilarQueryRecallResp> solvedQueries = getSimilarQueries(queryContext.getRequest().getQueryText(),
|
||||
queryContext.getRequest().getAgentId());
|
||||
ChatQueryDO chatQueryDO = getChatQuery(queryId);
|
||||
chatQueryDO.setSimilarQueries(JSONObject.toJSONString(solvedQueries));
|
||||
updateChatQuery(chatQueryDO);
|
||||
}
|
||||
|
||||
public List<SimilarQueryRecallResp> getSimilarQueries(String queryText, Integer agentId) {
|
||||
//1. recall solved query by queryText
|
||||
SimilarQueryManager solvedQueryManager = ContextUtils.getBean(SimilarQueryManager.class);
|
||||
List<SimilarQueryRecallResp> similarQueries = solvedQueryManager.recallSimilarQuery(queryText, agentId);
|
||||
if (CollectionUtils.isEmpty(similarQueries)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
//2. remove low score query
|
||||
List<Long> queryIds = similarQueries.stream()
|
||||
.map(SimilarQueryRecallResp::getQueryId).collect(Collectors.toList());
|
||||
int lowScoreThreshold = 3;
|
||||
List<QueryResp> queryResps = getChatQuery(queryIds);
|
||||
if (CollectionUtils.isEmpty(queryResps)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
Set<Long> lowScoreQueryIds = queryResps.stream().filter(queryResp ->
|
||||
queryResp.getScore() != null && queryResp.getScore() <= lowScoreThreshold)
|
||||
.map(QueryResp::getQuestionId).collect(Collectors.toSet());
|
||||
return similarQueries.stream().filter(solvedQueryRecallResp ->
|
||||
!lowScoreQueryIds.contains(solvedQueryRecallResp.getQueryId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private ChatQueryDO getChatQuery(Long queryId) {
|
||||
ChatQueryRepository chatQueryRepository = ContextUtils.getBean(ChatQueryRepository.class);
|
||||
return chatQueryRepository.getChatQueryDO(queryId);
|
||||
}
|
||||
|
||||
private List<QueryResp> getChatQuery(List<Long> queryIds) {
|
||||
ChatQueryRepository chatQueryRepository = ContextUtils.getBean(ChatQueryRepository.class);
|
||||
PageQueryInfoReq pageQueryInfoReq = new PageQueryInfoReq();
|
||||
pageQueryInfoReq.setIds(queryIds);
|
||||
pageQueryInfoReq.setPageSize(100);
|
||||
pageQueryInfoReq.setCurrent(1);
|
||||
PageInfo<QueryResp> queryRespPageInfo = chatQueryRepository.getChatQuery(pageQueryInfoReq, null);
|
||||
return queryRespPageInfo.getList();
|
||||
}
|
||||
|
||||
private void updateChatQuery(ChatQueryDO chatQueryDO) {
|
||||
ChatQueryRepository chatQueryRepository = ContextUtils.getBean(ChatQueryRepository.class);
|
||||
chatQueryRepository.updateChatQuery(chatQueryDO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.server.service.ChatService;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* RespBuildProcessor fill response object with parsing results.
|
||||
**/
|
||||
@Slf4j
|
||||
public class RespBuildProcessor implements ParseResultProcessor {
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
QueryReq queryReq = queryContext.getRequest();
|
||||
parseResp.setChatId(queryReq.getChatId());
|
||||
parseResp.setQueryText(queryReq.getQueryText());
|
||||
List<SemanticQuery> candidateQueries = queryContext.getCandidateQueries();
|
||||
ChatService chatService = ContextUtils.getBean(ChatService.class);
|
||||
if (candidateQueries.size() > 0) {
|
||||
List<SemanticParseInfo> candidateParses = candidateQueries.stream()
|
||||
.map(SemanticQuery::getParseInfo).collect(Collectors.toList());
|
||||
parseResp.setSelectedParses(candidateParses);
|
||||
parseResp.setState(ParseResp.ParseState.COMPLETED);
|
||||
} else {
|
||||
parseResp.setState(ParseResp.ParseState.FAILED);
|
||||
}
|
||||
chatService.batchAddParse(chatContext, queryReq, parseResp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SqlInfo;
|
||||
import com.tencent.supersonic.chat.core.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.core.query.llm.s2sql.LLMSqlQuery;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* SqlInfoProcessor adds S2SQL to the parsing results so that
|
||||
* technical users could verify SQL by themselves.
|
||||
**/
|
||||
public class SqlInfoProcessor implements ParseResultProcessor {
|
||||
|
||||
private static final Logger keyPipelineLog = LoggerFactory.getLogger("keyPipeline");
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
QueryReq queryReq = queryContext.getRequest();
|
||||
List<SemanticQuery> semanticQueries = queryContext.getCandidateQueries();
|
||||
if (CollectionUtils.isEmpty(semanticQueries)) {
|
||||
return;
|
||||
}
|
||||
List<SemanticParseInfo> selectedParses = semanticQueries.stream().map(SemanticQuery::getParseInfo)
|
||||
.collect(Collectors.toList());
|
||||
long startTime = System.currentTimeMillis();
|
||||
addSqlInfo(queryReq, selectedParses);
|
||||
parseResp.getParseTimeCost().setSqlTime(System.currentTimeMillis() - startTime);
|
||||
}
|
||||
|
||||
private void addSqlInfo(QueryReq queryReq, List<SemanticParseInfo> semanticParseInfos) {
|
||||
if (CollectionUtils.isEmpty(semanticParseInfos)) {
|
||||
return;
|
||||
}
|
||||
semanticParseInfos.forEach(parseInfo -> {
|
||||
addSqlInfo(queryReq, parseInfo);
|
||||
});
|
||||
}
|
||||
|
||||
private void addSqlInfo(QueryReq queryReq, SemanticParseInfo parseInfo) {
|
||||
SemanticQuery semanticQuery = QueryManager.createQuery(parseInfo.getQueryMode());
|
||||
if (Objects.isNull(semanticQuery)) {
|
||||
return;
|
||||
}
|
||||
semanticQuery.setParseInfo(parseInfo);
|
||||
String explainSql = semanticQuery.explain(queryReq.getUser());
|
||||
if (StringUtils.isBlank(explainSql)) {
|
||||
return;
|
||||
}
|
||||
SqlInfo sqlInfo = parseInfo.getSqlInfo();
|
||||
if (semanticQuery instanceof LLMSqlQuery) {
|
||||
keyPipelineLog.info("\ns2sql:{}\ncorrectS2SQL:{}\nquerySQL:{}", sqlInfo.getS2SQL(),
|
||||
sqlInfo.getCorrectS2SQL(), explainSql);
|
||||
}
|
||||
sqlInfo.setQuerySQL(explainSql);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.tencent.supersonic.chat.server.processor.parse;
|
||||
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* TimeCostProcessor adds time cost of parsing.
|
||||
**/
|
||||
@Slf4j
|
||||
public class TimeCostProcessor implements ParseResultProcessor {
|
||||
|
||||
@Override
|
||||
public void process(ParseResp parseResp, QueryContext queryContext, ChatContext chatContext) {
|
||||
long parseStartTime = parseResp.getParseTimeCost().getParseStartTime();
|
||||
parseResp.getParseTimeCost().setParseTime(
|
||||
System.currentTimeMillis() - parseStartTime - parseResp.getParseTimeCost().getSqlTime());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.tencent.supersonic.chat.server.rest;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.chat.core.agent.Agent;
|
||||
import com.tencent.supersonic.chat.server.service.AgentService;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping({"/api/chat/agent", "/openapi/chat/agent"})
|
||||
public class AgentController {
|
||||
|
||||
private AgentService agentService;
|
||||
|
||||
public AgentController(AgentService agentService) {
|
||||
this.agentService = agentService;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public boolean createAgent(@RequestBody Agent agent,
|
||||
HttpServletRequest httpServletRequest,
|
||||
HttpServletResponse httpServletResponse) {
|
||||
User user = UserHolder.findUser(httpServletRequest, httpServletResponse);
|
||||
agentService.createAgent(agent, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public boolean updateAgent(@RequestBody Agent agent,
|
||||
HttpServletRequest httpServletRequest,
|
||||
HttpServletResponse httpServletResponse) {
|
||||
User user = UserHolder.findUser(httpServletRequest, httpServletResponse);
|
||||
agentService.updateAgent(agent, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public boolean deleteAgent(@PathVariable("id") Integer id) {
|
||||
agentService.deleteAgent(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@RequestMapping("/getAgentList")
|
||||
public List<Agent> getAgentList() {
|
||||
return agentService.getAgents();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.tencent.supersonic.chat.server.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.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigBaseReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigEditReqReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.headless.api.request.PageDimensionReq;
|
||||
import com.tencent.supersonic.headless.api.request.PageMetricReq;
|
||||
import com.tencent.supersonic.headless.api.response.DimensionResp;
|
||||
import com.tencent.supersonic.headless.api.response.DomainResp;
|
||||
import com.tencent.supersonic.headless.api.response.MetricResp;
|
||||
import com.tencent.supersonic.headless.api.response.ModelResp;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping({"/api/chat/conf", "/openapi/chat/conf"})
|
||||
public class ChatConfigController {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
|
||||
private SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
|
||||
@PostMapping
|
||||
public Long addChatConfig(@RequestBody ChatConfigBaseReq extendBaseCmd,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return configService.addConfig(extendBaseCmd, user);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public Long editModelExtend(@RequestBody ChatConfigEditReqReq extendEditCmd,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return configService.editConfig(extendEditCmd, user);
|
||||
}
|
||||
|
||||
@PostMapping("/search")
|
||||
public List<ChatConfigResp> search(@RequestBody ChatConfigFilter filter,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return configService.search(filter, user);
|
||||
}
|
||||
|
||||
@GetMapping("/richDesc/{modelId}")
|
||||
public ChatConfigRichResp getModelExtendRichInfo(@PathVariable("modelId") Long modelId) {
|
||||
return configService.getConfigRichInfo(modelId);
|
||||
}
|
||||
|
||||
@GetMapping("/richDesc/all")
|
||||
public List<ChatConfigRichResp> getAllChatRichConfig() {
|
||||
return configService.getAllChatRichConfig();
|
||||
}
|
||||
|
||||
@GetMapping("/modelList/{domainId}")
|
||||
public List<ModelResp> getModelList(@PathVariable("domainId") Long domainId,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return semanticInterpreter.getModelList(AuthType.ADMIN, domainId, user);
|
||||
}
|
||||
|
||||
@GetMapping("/modelList")
|
||||
public List<ModelResp> getModelList(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return semanticInterpreter.getModelList(AuthType.ADMIN, null, user);
|
||||
}
|
||||
|
||||
@GetMapping("/domainList")
|
||||
public List<DomainResp> getDomainList(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return semanticInterpreter.getDomainList(user);
|
||||
}
|
||||
|
||||
@GetMapping("/modelList/view")
|
||||
public List<ModelResp> getModelListVisible(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return semanticInterpreter.getModelList(AuthType.VISIBLE, null, user);
|
||||
}
|
||||
|
||||
@PostMapping("/dimension/page")
|
||||
public PageInfo<DimensionResp> getDimension(@RequestBody PageDimensionReq pageDimensionReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return semanticInterpreter.getDimensionPage(pageDimensionReq);
|
||||
}
|
||||
|
||||
@PostMapping("/metric/page")
|
||||
public PageInfo<MetricResp> getMetric(@RequestBody PageMetricReq pageMetricReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return semanticInterpreter.getMetricPage(pageMetricReq, user);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.tencent.supersonic.chat.server.rest;
|
||||
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ShowCaseResp;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
|
||||
import com.tencent.supersonic.chat.server.service.ChatService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping({"/api/chat/manage", "/openapi/chat/manage"})
|
||||
public class ChatController {
|
||||
|
||||
private final ChatService chatService;
|
||||
|
||||
public ChatController(ChatService chatService) {
|
||||
this.chatService = chatService;
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public Boolean save(@RequestParam(value = "chatName") String chatName,
|
||||
@RequestParam(value = "agentId", required = false) Integer agentId,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
return chatService.addChat(UserHolder.findUser(request, response), chatName, agentId);
|
||||
}
|
||||
|
||||
@GetMapping("/getAll")
|
||||
public List<ChatDO> getAllConversions(@RequestParam(value = "agentId", required = false) Integer agentId,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
String userName = UserHolder.findUser(request, response).getName();
|
||||
return chatService.getAll(userName, agentId);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Boolean deleteConversion(@RequestParam(value = "chatId") long chatId,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
String userName = UserHolder.findUser(request, response).getName();
|
||||
return chatService.deleteChat(chatId, userName);
|
||||
}
|
||||
|
||||
@PostMapping("/updateChatName")
|
||||
public Boolean updateConversionName(@RequestParam(value = "chatId") Long chatId,
|
||||
@RequestParam(value = "chatName") String chatName,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
String userName = UserHolder.findUser(request, response).getName();
|
||||
return chatService.updateChatName(chatId, chatName, userName);
|
||||
}
|
||||
|
||||
@PostMapping("/updateQAFeedback")
|
||||
public Boolean updateQAFeedback(@RequestParam(value = "id") Integer id,
|
||||
@RequestParam(value = "score") Integer score,
|
||||
@RequestParam(value = "feedback", required = false) String feedback) {
|
||||
return chatService.updateFeedback(id, score, feedback);
|
||||
}
|
||||
|
||||
@PostMapping("/updateChatIsTop")
|
||||
public Boolean updateConversionIsTop(@RequestParam(value = "chatId") Long chatId,
|
||||
@RequestParam(value = "isTop") int isTop) {
|
||||
return chatService.updateChatIsTop(chatId, isTop);
|
||||
}
|
||||
|
||||
@PostMapping("/pageQueryInfo")
|
||||
public PageInfo<QueryResp> pageQueryInfo(@RequestBody PageQueryInfoReq pageQueryInfoCommand,
|
||||
@RequestParam(value = "chatId") long chatId,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
pageQueryInfoCommand.setUserName(UserHolder.findUser(request, response).getName());
|
||||
return chatService.queryInfo(pageQueryInfoCommand, chatId);
|
||||
}
|
||||
|
||||
@GetMapping("/getChatQuery/{queryId}")
|
||||
public QueryResp getChatQuery(@PathVariable("queryId") Long queryId) {
|
||||
return chatService.getChatQuery(queryId);
|
||||
}
|
||||
|
||||
@PostMapping("/queryShowCase")
|
||||
public ShowCaseResp queryShowCase(@RequestBody PageQueryInfoReq pageQueryInfoCommand,
|
||||
@RequestParam(value = "agentId") int agentId) {
|
||||
return chatService.queryShowCase(pageQueryInfoCommand, agentId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.tencent.supersonic.chat.server.rest;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DimensionValueReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryDataReq;
|
||||
import com.tencent.supersonic.chat.server.service.QueryService;
|
||||
import com.tencent.supersonic.chat.server.service.SearchService;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* query controller
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping({"/api/chat/query", "/openapi/chat/query"})
|
||||
public class ChatQueryController {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("chatQueryService")
|
||||
private QueryService queryService;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@PostMapping("search")
|
||||
public Object search(@RequestBody QueryReq queryCtx, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
queryCtx.setUser(UserHolder.findUser(request, response));
|
||||
return searchService.search(queryCtx);
|
||||
}
|
||||
|
||||
@PostMapping("parse")
|
||||
public Object parse(@RequestBody QueryReq queryCtx, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
queryCtx.setUser(UserHolder.findUser(request, response));
|
||||
return queryService.performParsing(queryCtx);
|
||||
}
|
||||
|
||||
@PostMapping("execute")
|
||||
public Object execute(@RequestBody ExecuteQueryReq queryReq,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
queryReq.setUser(UserHolder.findUser(request, response));
|
||||
return queryService.performExecution(queryReq);
|
||||
}
|
||||
|
||||
@PostMapping("queryContext")
|
||||
public Object queryContext(@RequestBody QueryReq queryCtx, HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
queryCtx.setUser(UserHolder.findUser(request, response));
|
||||
return queryService.queryContext(queryCtx);
|
||||
}
|
||||
|
||||
@PostMapping("queryData")
|
||||
public Object queryData(@RequestBody QueryDataReq queryData,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
queryData.setUser(UserHolder.findUser(request, response));
|
||||
return queryService.executeDirectQuery(queryData, UserHolder.findUser(request, response));
|
||||
}
|
||||
|
||||
@PostMapping("queryDimensionValue")
|
||||
public Object queryDimensionValue(@RequestBody @Valid DimensionValueReq dimensionValueReq,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
return queryService.queryDimensionValue(dimensionValueReq, UserHolder.findUser(request, response));
|
||||
}
|
||||
|
||||
@RequestMapping("/getEntityInfo")
|
||||
public Object getEntityInfo(Long queryId, Integer parseId,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return queryService.getEntityInfo(queryId, parseId, user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.tencent.supersonic.chat.server.rest;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictLatestTaskReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictTaskFilterReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.DictLatestTaskResp;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValue2DictCommand;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValueDictInfo;
|
||||
import com.tencent.supersonic.chat.server.listener.ApplicationStartedListener;
|
||||
import com.tencent.supersonic.chat.server.service.KnowledgeTaskService;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/chat/dict")
|
||||
public class KnowledgeController {
|
||||
|
||||
@Autowired
|
||||
private KnowledgeTaskService knowledgeTaskService;
|
||||
|
||||
@Autowired
|
||||
private ApplicationStartedListener applicationStartedListener;
|
||||
|
||||
/**
|
||||
* addDictInfo
|
||||
* write specific dimension values to the knowledge base
|
||||
*
|
||||
* @param dimValue2DictCommend
|
||||
*/
|
||||
@PostMapping("/task")
|
||||
public Long addDictTask(@RequestBody DimValue2DictCommand dimValue2DictCommend,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return knowledgeTaskService.addDictTask(dimValue2DictCommend, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* deleteDictInfo
|
||||
* remove specific dimension values from the knowledge base
|
||||
*
|
||||
* @param dimValue2DictCommend
|
||||
*/
|
||||
@PostMapping("/task/delete")
|
||||
public Long deleteDictTask(@RequestBody DimValue2DictCommand dimValue2DictCommend,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return knowledgeTaskService.deleteDictTask(dimValue2DictCommend, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* searchDictTaskList
|
||||
*
|
||||
* @param filter
|
||||
*/
|
||||
@PostMapping("/task/search")
|
||||
public List<DimValueDictInfo> searchDictTaskList(@RequestBody DictTaskFilterReq filter,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return knowledgeTaskService.searchDictTaskList(filter, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* searchDictLatestTaskList
|
||||
*/
|
||||
@PostMapping("/task/search/latest")
|
||||
public List<DictLatestTaskResp> searchDictLatestTaskList(@RequestBody @Valid DictLatestTaskReq filter,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return knowledgeTaskService.searchDictLatestTaskList(filter, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* getDictRootPath
|
||||
* get knowledge base file directory
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/rootPath")
|
||||
public String getDictRootPath(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return knowledgeTaskService.getDictRootPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* updateDimValue
|
||||
* update in-memory dictionary files in real time
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/knowledge/dimValue")
|
||||
public Boolean updateDimValue(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return applicationStartedListener.updateKnowledgeDimValue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.tencent.supersonic.chat.server.rest;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PluginQueryReq;
|
||||
import com.tencent.supersonic.chat.core.plugin.Plugin;
|
||||
import com.tencent.supersonic.chat.server.service.PluginService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/chat/plugin")
|
||||
public class PluginController {
|
||||
|
||||
@Autowired
|
||||
protected PluginService pluginService;
|
||||
|
||||
@PostMapping
|
||||
public boolean createPlugin(@RequestBody Plugin plugin,
|
||||
HttpServletRequest httpServletRequest,
|
||||
HttpServletResponse httpServletResponse) {
|
||||
User user = UserHolder.findUser(httpServletRequest, httpServletResponse);
|
||||
pluginService.createPlugin(plugin, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public boolean updatePlugin(@RequestBody Plugin plugin,
|
||||
HttpServletRequest httpServletRequest,
|
||||
HttpServletResponse httpServletResponse) {
|
||||
User user = UserHolder.findUser(httpServletRequest, httpServletResponse);
|
||||
pluginService.updatePlugin(plugin, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public boolean deletePlugin(@PathVariable("id") Long id) {
|
||||
pluginService.deletePlugin(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@RequestMapping("/getPluginList")
|
||||
public List<Plugin> getPluginList() {
|
||||
return pluginService.getPluginList();
|
||||
}
|
||||
|
||||
@PostMapping("/query")
|
||||
List<Plugin> query(@RequestBody PluginQueryReq pluginQueryReq,
|
||||
HttpServletRequest httpServletRequest,
|
||||
HttpServletResponse httpServletResponse) {
|
||||
User user = UserHolder.findUser(httpServletRequest, httpServletResponse);
|
||||
return pluginService.queryWithAuthCheck(pluginQueryReq, user);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.tencent.supersonic.chat.server.rest;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.RecommendQuestionResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.RecommendResp;
|
||||
import com.tencent.supersonic.chat.server.service.RecommendService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* recommend controller
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping({"/api/chat/", "/openapi/chat/"})
|
||||
public class RecommendController {
|
||||
|
||||
@Autowired
|
||||
private RecommendService recommendService;
|
||||
|
||||
@GetMapping("recommend/{modelId}")
|
||||
public RecommendResp recommend(@PathVariable("modelId") Long modelId,
|
||||
@RequestParam(value = "limit", required = false) Long limit) {
|
||||
RecommendReq recommendReq = new RecommendReq();
|
||||
recommendReq.setModelId(modelId);
|
||||
return recommendService.recommend(recommendReq, limit);
|
||||
}
|
||||
|
||||
@GetMapping("recommend/metric/{modelId}")
|
||||
public RecommendResp recommendMetricMode(@PathVariable("modelId") Long modelId,
|
||||
@RequestParam(value = "metricId", required = false) Long metricId,
|
||||
@RequestParam(value = "limit", required = false) Long limit) {
|
||||
RecommendReq recommendReq = new RecommendReq();
|
||||
recommendReq.setModelId(modelId);
|
||||
recommendReq.setMetricId(metricId);
|
||||
return recommendService.recommendMetricMode(recommendReq, limit);
|
||||
}
|
||||
|
||||
@GetMapping("recommend/question")
|
||||
public List<RecommendQuestionResp> recommendQuestion(
|
||||
@RequestParam(value = "modelId", required = false) Long modelId) {
|
||||
return recommendService.recommendQuestion(modelId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.core.agent.Agent;
|
||||
import java.util.List;
|
||||
|
||||
public interface AgentService {
|
||||
|
||||
List<Agent> getAgents();
|
||||
|
||||
void createAgent(Agent agent, User user);
|
||||
|
||||
void updateAgent(Agent agent, User user);
|
||||
|
||||
Agent getAgent(Integer id);
|
||||
|
||||
void deleteAgent(Integer id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ShowCaseResp;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ChatService {
|
||||
|
||||
/***
|
||||
* get the model from context
|
||||
* @param chatId
|
||||
* @return
|
||||
*/
|
||||
Set<Long> getContextModel(Integer chatId);
|
||||
|
||||
ChatContext getOrCreateContext(int chatId);
|
||||
|
||||
void updateContext(ChatContext chatCtx);
|
||||
|
||||
Boolean addChat(User user, String chatName, Integer agentId);
|
||||
|
||||
List<ChatDO> getAll(String userName, Integer agentId);
|
||||
|
||||
boolean updateChatName(Long chatId, String chatName, String userName);
|
||||
|
||||
boolean updateFeedback(Integer id, Integer score, String feedback);
|
||||
|
||||
boolean updateChatIsTop(Long chatId, int isTop);
|
||||
|
||||
Boolean deleteChat(Long chatId, String userName);
|
||||
|
||||
PageInfo<QueryResp> queryInfo(PageQueryInfoReq pageQueryInfoCommend, long chatId);
|
||||
|
||||
QueryResp getChatQuery(Long queryId);
|
||||
|
||||
ShowCaseResp queryShowCase(PageQueryInfoReq pageQueryInfoCommend, int agentId);
|
||||
|
||||
List<ChatParseDO> batchAddParse(ChatContext chatCtx, QueryReq queryReq, ParseResp parseResult);
|
||||
|
||||
ChatQueryDO getLastQuery(long chatId);
|
||||
|
||||
int updateQuery(ChatQueryDO chatQueryDO);
|
||||
|
||||
void updateQuery(Long questionId, int parseId, QueryResult queryResult, ChatContext chatCtx);
|
||||
|
||||
ChatParseDO getParseInfo(Long questionId, int parseId);
|
||||
|
||||
Boolean deleteChatQuery(Long questionId);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigBaseReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigEditReqReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ItemNameVisibilityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfig;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ConfigService {
|
||||
|
||||
Long addConfig(ChatConfigBaseReq extendBaseCmd, User user);
|
||||
|
||||
Long editConfig(ChatConfigEditReqReq extendEditCmd, User user);
|
||||
|
||||
ItemNameVisibilityInfo getItemNameVisibility(ChatConfig chatConfig);
|
||||
|
||||
ItemNameVisibilityInfo getVisibilityByModelId(Long modelId);
|
||||
|
||||
List<ChatConfigResp> search(ChatConfigFilter filter, User user);
|
||||
|
||||
ChatConfigRichResp getConfigRichInfo(Long modelId);
|
||||
|
||||
ChatConfigResp fetchConfigByModelId(Long modelId);
|
||||
|
||||
List<ChatConfigRichResp> getAllChatRichConfig();
|
||||
|
||||
Map<Long, ChatConfigRichResp> getModelIdToChatRichConfig();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictWord;
|
||||
import java.util.List;
|
||||
|
||||
public interface KnowledgeService {
|
||||
|
||||
void updateSemanticKnowledge(List<DictWord> natures);
|
||||
|
||||
void reloadAllData(List<DictWord> natures);
|
||||
|
||||
void updateOnlineKnowledge(List<DictWord> natures);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictLatestTaskReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictTaskFilterReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.DictLatestTaskResp;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictConfig;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValue2DictCommand;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValueDictInfo;
|
||||
import java.util.List;
|
||||
|
||||
public interface KnowledgeTaskService {
|
||||
Long addDictTask(DimValue2DictCommand dimValue2DictCommend, User user);
|
||||
|
||||
Long deleteDictTask(DimValue2DictCommand dimValue2DictCommend, User user);
|
||||
|
||||
List<DimValueDictInfo> searchDictTaskList(DictTaskFilterReq filter, User user);
|
||||
|
||||
DictConfig getDictInfoByModelId(Long modelId);
|
||||
|
||||
String getDictRootPath();
|
||||
|
||||
List<DictLatestTaskResp> searchDictLatestTaskList(DictLatestTaskReq filter, User user);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PluginQueryReq;
|
||||
import com.tencent.supersonic.chat.core.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface PluginService {
|
||||
|
||||
void createPlugin(Plugin plugin, User user);
|
||||
|
||||
void updatePlugin(Plugin plugin, User user);
|
||||
|
||||
void deletePlugin(Long id);
|
||||
|
||||
List<Plugin> getPluginList();
|
||||
|
||||
List<Plugin> fetchPluginDOs(String queryText, String type);
|
||||
|
||||
List<Plugin> query(PluginQueryReq pluginQueryReq);
|
||||
|
||||
Optional<Plugin> getPluginByName(String name);
|
||||
|
||||
List<Plugin> queryWithAuthCheck(PluginQueryReq pluginQueryReq, User user);
|
||||
|
||||
Map<String, Plugin> getNameToPlugin();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DimensionValueReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryDataReq;
|
||||
import org.apache.calcite.sql.parser.SqlParseException;
|
||||
|
||||
/***
|
||||
* QueryService for query and search
|
||||
*/
|
||||
public interface QueryService {
|
||||
|
||||
ParseResp performParsing(QueryReq queryReq);
|
||||
|
||||
QueryResult performExecution(ExecuteQueryReq queryReq) throws Exception;
|
||||
|
||||
SemanticParseInfo queryContext(QueryReq queryReq);
|
||||
|
||||
QueryResult executeDirectQuery(QueryDataReq queryData, User user) throws SqlParseException;
|
||||
|
||||
EntityInfo getEntityInfo(Long queryId, Integer parseId, User user);
|
||||
|
||||
Object queryDimensionValue(DimensionValueReq dimensionValueReq, User user) throws Exception;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.RecommendQuestionResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.RecommendResp;
|
||||
import java.util.List;
|
||||
|
||||
/***
|
||||
* Recommend Service
|
||||
*/
|
||||
public interface RecommendService {
|
||||
|
||||
RecommendResp recommend(RecommendReq recommendReq, Long limit);
|
||||
|
||||
RecommendResp recommendMetricMode(RecommendReq recommendReq, Long limit);
|
||||
|
||||
List<RecommendQuestionResp> recommendQuestion(Long modelId);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SearchResult;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* search service
|
||||
*/
|
||||
public interface SearchService {
|
||||
|
||||
List<SearchResult> search(QueryReq queryCtx);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatDefaultRichConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.DataInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ModelInfo;
|
||||
import com.tencent.supersonic.chat.core.config.AggregatorConfig;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.core.utils.QueryReqBuilder;
|
||||
import com.tencent.supersonic.chat.server.service.impl.SchemaService;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.DateConf.DateMode;
|
||||
import com.tencent.supersonic.common.pojo.ModelCluster;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.headless.api.request.QueryStructReq;
|
||||
import com.tencent.supersonic.headless.api.response.QueryResultWithSchemaResp;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
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.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SemanticService {
|
||||
|
||||
@Autowired
|
||||
private SchemaService schemaService;
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private AggregatorConfig aggregatorConfig;
|
||||
|
||||
private SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
|
||||
public SemanticSchema getSemanticSchema() {
|
||||
return schemaService.getSemanticSchema();
|
||||
}
|
||||
|
||||
public ModelSchema getModelSchema(Long id) {
|
||||
return schemaService.getModelSchema(id);
|
||||
}
|
||||
|
||||
public EntityInfo getEntityInfo(SemanticParseInfo parseInfo, User user) {
|
||||
if (parseInfo != null && parseInfo.getModelId() > 0) {
|
||||
EntityInfo entityInfo = getEntityInfo(parseInfo.getModelId());
|
||||
if (parseInfo.getDimensionFilters().size() <= 0 || entityInfo.getModelInfo() == null) {
|
||||
entityInfo.setMetrics(null);
|
||||
entityInfo.setDimensions(null);
|
||||
return entityInfo;
|
||||
}
|
||||
String primaryKey = entityInfo.getModelInfo().getPrimaryKey();
|
||||
if (StringUtils.isNotBlank(primaryKey)) {
|
||||
String modelInfoId = "";
|
||||
for (QueryFilter chatFilter : parseInfo.getDimensionFilters()) {
|
||||
if (chatFilter != null && chatFilter.getBizName() != null && chatFilter.getBizName()
|
||||
.equals(primaryKey)) {
|
||||
if (chatFilter.getOperator().equals(FilterOperatorEnum.EQUALS)) {
|
||||
modelInfoId = chatFilter.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
setMainModel(entityInfo, parseInfo, modelInfoId, user);
|
||||
return entityInfo;
|
||||
} catch (Exception e) {
|
||||
log.error("setMainModel error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public EntityInfo getEntityInfo(Long model) {
|
||||
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(model);
|
||||
if (Objects.isNull(chaConfigRichDesc) || Objects.isNull(chaConfigRichDesc.getChatDetailRichConfig())) {
|
||||
return new EntityInfo();
|
||||
}
|
||||
return getEntityInfo(chaConfigRichDesc);
|
||||
}
|
||||
|
||||
private EntityInfo getEntityInfo(ChatConfigRichResp chaConfigRichDesc) {
|
||||
|
||||
EntityInfo entityInfo = new EntityInfo();
|
||||
Long modelId = chaConfigRichDesc.getModelId();
|
||||
if (Objects.nonNull(chaConfigRichDesc) && Objects.nonNull(modelId)) {
|
||||
SemanticService schemaService = ContextUtils.getBean(SemanticService.class);
|
||||
ModelSchema modelSchema = schemaService.getModelSchema(modelId);
|
||||
if (Objects.isNull(modelSchema) || Objects.isNull(modelSchema.getEntity())) {
|
||||
return entityInfo;
|
||||
}
|
||||
ModelInfo modelInfo = new ModelInfo();
|
||||
modelInfo.setItemId(modelId.intValue());
|
||||
modelInfo.setName(modelSchema.getModel().getName());
|
||||
modelInfo.setWords(modelSchema.getModel().getAlias());
|
||||
modelInfo.setBizName(modelSchema.getModel().getBizName());
|
||||
if (Objects.nonNull(modelSchema.getEntity())) {
|
||||
modelInfo.setPrimaryKey(modelSchema.getEntity().getBizName());
|
||||
}
|
||||
|
||||
entityInfo.setModelInfo(modelInfo);
|
||||
List<DataInfo> dimensions = new ArrayList<>();
|
||||
List<DataInfo> metrics = new ArrayList<>();
|
||||
|
||||
if (Objects.nonNull(chaConfigRichDesc) && Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig())
|
||||
&& Objects.nonNull(chaConfigRichDesc.getChatDetailRichConfig().getChatDefaultConfig())) {
|
||||
ChatDefaultRichConfigResp chatDefaultConfig = chaConfigRichDesc.getChatDetailRichConfig()
|
||||
.getChatDefaultConfig();
|
||||
if (!CollectionUtils.isEmpty(chatDefaultConfig.getDimensions())) {
|
||||
for (SchemaElement dimensionDesc : chatDefaultConfig.getDimensions()) {
|
||||
DataInfo mainEntityDimension = new DataInfo();
|
||||
mainEntityDimension.setItemId(dimensionDesc.getId().intValue());
|
||||
mainEntityDimension.setName(dimensionDesc.getName());
|
||||
mainEntityDimension.setBizName(dimensionDesc.getBizName());
|
||||
dimensions.add(mainEntityDimension);
|
||||
}
|
||||
entityInfo.setDimensions(dimensions);
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())) {
|
||||
for (SchemaElement metricDesc : chatDefaultConfig.getMetrics()) {
|
||||
DataInfo dataInfo = new DataInfo();
|
||||
dataInfo.setName(metricDesc.getName());
|
||||
dataInfo.setBizName(metricDesc.getBizName());
|
||||
dataInfo.setItemId(metricDesc.getId().intValue());
|
||||
metrics.add(dataInfo);
|
||||
}
|
||||
entityInfo.setMetrics(metrics);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entityInfo;
|
||||
}
|
||||
|
||||
public void setMainModel(EntityInfo modelInfo, SemanticParseInfo parseInfo, String entity, User user) {
|
||||
if (StringUtils.isEmpty(entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> entities = Collections.singletonList(entity);
|
||||
|
||||
QueryResultWithSchemaResp queryResultWithColumns = getQueryResultWithSchemaResp(modelInfo, parseInfo, entities,
|
||||
user);
|
||||
|
||||
if (queryResultWithColumns != null) {
|
||||
if (!CollectionUtils.isEmpty(queryResultWithColumns.getResultList())
|
||||
&& queryResultWithColumns.getResultList().size() > 0) {
|
||||
Map<String, Object> result = queryResultWithColumns.getResultList().get(0);
|
||||
for (Map.Entry<String, Object> entry : result.entrySet()) {
|
||||
String entryKey = getEntryKey(entry);
|
||||
if (entry.getValue() == null || entryKey == null) {
|
||||
continue;
|
||||
}
|
||||
modelInfo.getDimensions().stream().filter(i -> entryKey.equals(i.getBizName()))
|
||||
.forEach(i -> i.setValue(entry.getValue().toString()));
|
||||
modelInfo.getMetrics().stream().filter(i -> entryKey.equals(i.getBizName()))
|
||||
.forEach(i -> i.setValue(entry.getValue().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public QueryResultWithSchemaResp getQueryResultWithSchemaResp(EntityInfo modelInfo, SemanticParseInfo parseInfo,
|
||||
List<String> entities, User user) {
|
||||
if (CollectionUtils.isEmpty(entities)) {
|
||||
return null;
|
||||
}
|
||||
ModelSchema modelSchema = schemaService.getModelSchema(parseInfo.getModelId());
|
||||
modelInfo.setEntityId(entities.get(0));
|
||||
SemanticParseInfo semanticParseInfo = new SemanticParseInfo();
|
||||
semanticParseInfo.setModel(ModelCluster.build(Sets.newHashSet(parseInfo.getModelId())));
|
||||
semanticParseInfo.setQueryType(QueryType.TAG);
|
||||
semanticParseInfo.setMetrics(getMetrics(modelInfo));
|
||||
semanticParseInfo.setDimensions(getDimensions(modelInfo));
|
||||
DateConf dateInfo = new DateConf();
|
||||
int unit = 1;
|
||||
ChatConfigResp chatConfigInfo =
|
||||
configService.fetchConfigByModelId(modelSchema.getModel().getId());
|
||||
if (Objects.nonNull(chatConfigInfo) && Objects.nonNull(chatConfigInfo.getChatDetailConfig())
|
||||
&& Objects.nonNull(chatConfigInfo.getChatDetailConfig().getChatDefaultConfig())) {
|
||||
ChatDefaultConfigReq chatDefaultConfig = chatConfigInfo.getChatDetailConfig().getChatDefaultConfig();
|
||||
unit = chatDefaultConfig.getUnit();
|
||||
String date = LocalDate.now().plusDays(-unit).toString();
|
||||
dateInfo.setDateMode(DateMode.BETWEEN);
|
||||
dateInfo.setStartDate(date);
|
||||
dateInfo.setEndDate(date);
|
||||
} else {
|
||||
dateInfo.setUnit(unit);
|
||||
dateInfo.setDateMode(DateMode.RECENT);
|
||||
}
|
||||
semanticParseInfo.setDateInfo(dateInfo);
|
||||
|
||||
// add filter
|
||||
QueryFilter chatFilter = getQueryFilter(modelInfo, entities);
|
||||
Set<QueryFilter> chatFilters = new LinkedHashSet();
|
||||
chatFilters.add(chatFilter);
|
||||
semanticParseInfo.setDimensionFilters(chatFilters);
|
||||
|
||||
QueryResultWithSchemaResp queryResultWithColumns = null;
|
||||
try {
|
||||
QueryStructReq queryStructReq = QueryReqBuilder.buildStructReq(semanticParseInfo);
|
||||
queryResultWithColumns = semanticInterpreter.queryByStruct(queryStructReq, user);
|
||||
} catch (Exception e) {
|
||||
log.warn("setMainModel queryByStruct error, e:", e);
|
||||
}
|
||||
return queryResultWithColumns;
|
||||
}
|
||||
|
||||
private QueryFilter getQueryFilter(EntityInfo modelInfo, List<String> entities) {
|
||||
QueryFilter chatFilter = new QueryFilter();
|
||||
if (entities.size() == 1) {
|
||||
chatFilter.setValue(entities.get(0));
|
||||
chatFilter.setOperator(FilterOperatorEnum.EQUALS);
|
||||
} else {
|
||||
chatFilter.setValue(entities);
|
||||
chatFilter.setOperator(FilterOperatorEnum.IN);
|
||||
}
|
||||
chatFilter.setBizName(getEntityPrimaryName(modelInfo));
|
||||
return chatFilter;
|
||||
}
|
||||
|
||||
private Set<SchemaElement> getDimensions(EntityInfo modelInfo) {
|
||||
Set<SchemaElement> dimensions = new LinkedHashSet();
|
||||
for (DataInfo mainEntityDimension : modelInfo.getDimensions()) {
|
||||
SchemaElement dimension = new SchemaElement();
|
||||
dimension.setBizName(mainEntityDimension.getBizName());
|
||||
dimensions.add(dimension);
|
||||
}
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
private String getEntryKey(Map.Entry<String, Object> entry) {
|
||||
// metric parser special handle, TODO delete
|
||||
String entryKey = entry.getKey();
|
||||
if (entryKey.contains("__")) {
|
||||
entryKey = entryKey.split("__")[1];
|
||||
}
|
||||
return entryKey;
|
||||
}
|
||||
|
||||
private Set<SchemaElement> getMetrics(EntityInfo modelInfo) {
|
||||
Set<SchemaElement> metrics = new LinkedHashSet();
|
||||
for (DataInfo metricValue : modelInfo.getMetrics()) {
|
||||
SchemaElement metric = new SchemaElement();
|
||||
BeanUtils.copyProperties(metricValue, metric);
|
||||
metrics.add(metric);
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private String getEntityPrimaryName(EntityInfo modelInfo) {
|
||||
return modelInfo.getModelInfo().getPrimaryKey();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.StatisticsDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StatisticsService {
|
||||
void batchSaveStatistics(List<StatisticsDO> list);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TimeCost {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tencent.supersonic.chat.server.service;
|
||||
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@Aspect
|
||||
public class TimeCostAOP {
|
||||
|
||||
@Pointcut("@annotation(com.tencent.supersonic.chat.server.service.TimeCost)")
|
||||
private void timeCostAdvicePointcut() {
|
||||
|
||||
}
|
||||
|
||||
@Around("timeCostAdvicePointcut()")
|
||||
public Object timeCostAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
log.info("begin to add time cost!");
|
||||
Long startTime = System.currentTimeMillis();
|
||||
Object object = joinPoint.proceed();
|
||||
if (object instanceof QueryResult) {
|
||||
QueryResult queryResult = (QueryResult) object;
|
||||
queryResult.setQueryTimeCost(System.currentTimeMillis() - startTime);
|
||||
return queryResult;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.core.agent.Agent;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.AgentRepository;
|
||||
import com.tencent.supersonic.chat.server.service.AgentService;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AgentServiceImpl implements AgentService {
|
||||
|
||||
private AgentRepository agentRepository;
|
||||
|
||||
public AgentServiceImpl(AgentRepository agentRepository) {
|
||||
this.agentRepository = agentRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Agent> getAgents() {
|
||||
return getAgentDOList().stream()
|
||||
.map(this::convert).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAgent(Agent agent, User user) {
|
||||
agentRepository.createAgent(convert(agent, user));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAgent(Agent agent, User user) {
|
||||
agentRepository.updateAgent(convert(agent, user));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Agent getAgent(Integer id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
return convert(agentRepository.getAgent(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAgent(Integer id) {
|
||||
agentRepository.deleteAgent(id);
|
||||
}
|
||||
|
||||
private List<AgentDO> getAgentDOList() {
|
||||
return agentRepository.getAgents();
|
||||
}
|
||||
|
||||
private Agent convert(AgentDO agentDO) {
|
||||
if (agentDO == null) {
|
||||
return null;
|
||||
}
|
||||
Agent agent = new Agent();
|
||||
BeanUtils.copyProperties(agentDO, agent);
|
||||
agent.setAgentConfig(agentDO.getConfig());
|
||||
agent.setExamples(JSONObject.parseArray(agentDO.getExamples(), String.class));
|
||||
return agent;
|
||||
}
|
||||
|
||||
private AgentDO convert(Agent agent, User user) {
|
||||
AgentDO agentDO = new AgentDO();
|
||||
BeanUtils.copyProperties(agent, agentDO);
|
||||
agentDO.setConfig(agent.getAgentConfig());
|
||||
agentDO.setExamples(JSONObject.toJSONString(agent.getExamples()));
|
||||
agentDO.setCreatedAt(new Date());
|
||||
agentDO.setCreatedBy(user.getName());
|
||||
agentDO.setUpdatedAt(new Date());
|
||||
agentDO.setUpdatedBy(user.getName());
|
||||
if (agentDO.getStatus() == null) {
|
||||
agentDO.setStatus(1);
|
||||
}
|
||||
return agentDO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictLatestTaskReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DictTaskFilterReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.DictLatestTaskResp;
|
||||
import com.tencent.supersonic.chat.core.config.DefaultMetric;
|
||||
import com.tencent.supersonic.chat.core.config.Dim4Dict;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictConfig;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictUpdateMode;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValue2DictCommand;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValueDictInfo;
|
||||
import com.tencent.supersonic.chat.core.knowledge.FileHandler;
|
||||
import com.tencent.supersonic.chat.core.utils.DictQueryHelper;
|
||||
import com.tencent.supersonic.chat.server.listener.ApplicationStartedListener;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictTaskDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DimValueDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.DictRepository;
|
||||
import com.tencent.supersonic.chat.server.service.KnowledgeTaskService;
|
||||
import com.tencent.supersonic.chat.server.util.DictMetaHelper;
|
||||
import com.tencent.supersonic.chat.server.util.DictTaskConverter;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ChatKnowledgeTaskServiceImpl implements KnowledgeTaskService {
|
||||
|
||||
private final DictMetaHelper metaUtils;
|
||||
private final DictQueryHelper dictQueryHelper;
|
||||
private final FileHandler fileHandler;
|
||||
private final DictRepository dictRepository;
|
||||
private final ApplicationStartedListener applicationStartedListener;
|
||||
|
||||
@Value("${dict.flush.enable:true}")
|
||||
private Boolean dictFlushEnable;
|
||||
@Value("${dict.flush.daily.enable:true}")
|
||||
private Boolean dictFlushDailyEnable;
|
||||
@Value("${dict.file.type:txt}")
|
||||
private String dictFileType;
|
||||
private String dimValue = "DimValue_%d_%d";
|
||||
|
||||
public ChatKnowledgeTaskServiceImpl(DictMetaHelper metaUtils,
|
||||
DictQueryHelper dictQueryHelper,
|
||||
FileHandler fileHandler,
|
||||
DictRepository dictRepository,
|
||||
ApplicationStartedListener applicationStartedListener) {
|
||||
this.metaUtils = metaUtils;
|
||||
this.dictQueryHelper = dictQueryHelper;
|
||||
this.fileHandler = fileHandler;
|
||||
this.dictRepository = dictRepository;
|
||||
this.applicationStartedListener = applicationStartedListener;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "${knowledge.dimension.value.cron:0 0 0 * * ?}")
|
||||
public Boolean dailyDictTask() {
|
||||
log.info("[dailyDictTask] start");
|
||||
if (!dictFlushDailyEnable) {
|
||||
log.info("dictFlushDailyEnable is false, now finish dailyDictTask");
|
||||
}
|
||||
DimValue2DictCommand dimValue2DictCommend = new DimValue2DictCommand();
|
||||
dimValue2DictCommend.setUpdateMode(DictUpdateMode.OFFLINE_FULL);
|
||||
|
||||
User user = User.getFakeUser();
|
||||
addDictTask(dimValue2DictCommend, user);
|
||||
log.info("[dailyDictTask] finish");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long addDictTask(DimValue2DictCommand dimValue2DictCommend, User user) {
|
||||
if (!dictFlushEnable) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
if (DictUpdateMode.REALTIME_DELETE.equals(dimValue2DictCommend.getUpdateMode())) {
|
||||
return deleteDictTask(dimValue2DictCommend, user);
|
||||
}
|
||||
|
||||
DictTaskDO dictTaskDO = DictTaskConverter.generateDimValueDictTaskDO(dimValue2DictCommend, user);
|
||||
log.info("[addDictTask] dictTaskDO:{}", dictTaskDO);
|
||||
// todo check dimension can not be searched
|
||||
|
||||
dictRepository.createDimValueDictTask(dictTaskDO);
|
||||
runDictTask(dictTaskDO, user);
|
||||
|
||||
return dictTaskDO.getId();
|
||||
}
|
||||
|
||||
public Long runDictTask(DictTaskDO dictTaskDO, User user) {
|
||||
if (Objects.isNull(dictTaskDO)) {
|
||||
return -1L;
|
||||
}
|
||||
DimValue2DictCommand command = JsonUtil.toObject(dictTaskDO.getCommand(), DimValue2DictCommand.class);
|
||||
try {
|
||||
//1. construct internal dictionary requirements
|
||||
List<DimValueDO> dimValueDOList = metaUtils.generateDimValueInfo(command);
|
||||
Set<Long> dimIds = generateDimSet(dimValueDOList);
|
||||
dictTaskDO.setDimIds(JsonUtil.toString(dimIds));
|
||||
dictRepository.updateDictTaskStatus(TaskStatusEnum.RUNNING.getCode(), dictTaskDO);
|
||||
log.debug("dimValueDOList:{}", dimValueDOList);
|
||||
//2. query dimension value information
|
||||
for (DimValueDO dimValueDO : dimValueDOList) {
|
||||
Long modelId = dimValueDO.getModelId();
|
||||
DefaultMetric defaultMetricDesc = dimValueDO.getDefaultMetricDescList().get(0);
|
||||
for (Dim4Dict dim4Dict : dimValueDO.getDimensions()) {
|
||||
List<String> data = dictQueryHelper.fetchDimValueSingle(modelId, defaultMetricDesc, dim4Dict, user);
|
||||
//3. local file changes
|
||||
String fileName = String.format(dimValue + Constants.DOT + dictFileType, modelId,
|
||||
dim4Dict.getDimId());
|
||||
fileHandler.writeFile(data, fileName, false);
|
||||
}
|
||||
}
|
||||
applicationStartedListener.updateKnowledgeDimValue();
|
||||
log.debug("updateDictTaskStatus to SUCCESS");
|
||||
dictRepository.updateDictTaskStatus(TaskStatusEnum.SUCCESS.getCode(), dictTaskDO);
|
||||
} catch (Exception e) {
|
||||
log.warn("addDictInfo exception:", e);
|
||||
dictRepository.updateDictTaskStatus(TaskStatusEnum.ERROR.getCode(), dictTaskDO);
|
||||
}
|
||||
return 1L;
|
||||
}
|
||||
|
||||
private Set<Long> generateDimSet(List<DimValueDO> dimValueDOList) {
|
||||
Set<Long> dimIds = new HashSet<>();
|
||||
if (!CollectionUtils.isEmpty(dimValueDOList)) {
|
||||
dimValueDOList.stream().forEach(dimValueDO -> {
|
||||
if (!CollectionUtils.isEmpty(dimValueDO.getDimensions())) {
|
||||
dimValueDO.getDimensions().stream().forEach(dim4Dict -> dimIds.add(dim4Dict.getDimId()));
|
||||
}
|
||||
});
|
||||
}
|
||||
return dimIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long deleteDictTask(DimValue2DictCommand dimValue2DictCommand, User user) {
|
||||
if (!dictFlushEnable) {
|
||||
return 0L;
|
||||
}
|
||||
if (Objects.isNull(dimValue2DictCommand) || !DictUpdateMode.REALTIME_DELETE.equals(
|
||||
dimValue2DictCommand.getUpdateMode())) {
|
||||
throw new RuntimeException("illegal parameter");
|
||||
}
|
||||
|
||||
DictTaskDO dictTaskDO = DictTaskConverter.generateDimValueDictTaskDO(dimValue2DictCommand, user);
|
||||
log.info("[deleteDictTask] dictTaskDO:{}", dictTaskDO);
|
||||
Set<Long> dimIds = generateDimSetFromCommand(dimValue2DictCommand.getModelAndDimPair());
|
||||
dictTaskDO.setDimIds(JsonUtil.toString(dimIds));
|
||||
dictRepository.createDimValueDictTask(dictTaskDO);
|
||||
|
||||
Map<Long, List<Long>> modelAndDimPair = dimValue2DictCommand.getModelAndDimPair();
|
||||
if (CollectionUtils.isEmpty(modelAndDimPair)) {
|
||||
return 0L;
|
||||
}
|
||||
for (Long modelId : modelAndDimPair.keySet()) {
|
||||
if (CollectionUtils.isEmpty(modelAndDimPair.get(modelId))) {
|
||||
continue;
|
||||
}
|
||||
for (Long dimId : modelAndDimPair.get(modelId)) {
|
||||
String fileName = String.format(dimValue + Constants.DOT + dictFileType, modelId, dimId);
|
||||
fileHandler.deleteDictFile(fileName);
|
||||
}
|
||||
}
|
||||
applicationStartedListener.updateKnowledgeDimValue();
|
||||
dictRepository.updateDictTaskStatus(TaskStatusEnum.SUCCESS.getCode(), dictTaskDO);
|
||||
applicationStartedListener.updateKnowledgeDimValue();
|
||||
|
||||
return 1L;
|
||||
}
|
||||
|
||||
private Set<Long> generateDimSetFromCommand(Map<Long, List<Long>> modelAndDimPair) {
|
||||
Set<Long> dimIds = new HashSet<>();
|
||||
if (!CollectionUtils.isEmpty(modelAndDimPair)) {
|
||||
modelAndDimPair.forEach((k, v) -> dimIds.addAll(v));
|
||||
}
|
||||
return dimIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDictRootPath() {
|
||||
return fileHandler.getDictRootPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictLatestTaskResp> searchDictLatestTaskList(DictLatestTaskReq latestFilter, User user) {
|
||||
DictTaskFilterReq filter = new DictTaskFilterReq();
|
||||
BeanUtils.copyProperties(latestFilter, filter);
|
||||
List<DimValueDictInfo> dimValueDictInfoList = searchDictTaskList(filter, user);
|
||||
return extractLatestTask(dimValueDictInfoList, latestFilter.getDimIds());
|
||||
}
|
||||
|
||||
private List<DictLatestTaskResp> extractLatestTask(List<DimValueDictInfo> dimValueDictInfoList, List<Long> dimIds) {
|
||||
List<DictLatestTaskResp> dictLatestTaskRespList = new ArrayList<>();
|
||||
Map<Long, DictLatestTaskResp> dimAndTaskPair = new HashMap<>(50);
|
||||
for (DimValueDictInfo dimValueDictInfo : dimValueDictInfoList) {
|
||||
//1. filter
|
||||
if (Objects.isNull(dimValueDictInfo) || CollectionUtils.isEmpty(dimValueDictInfo.getDimIds())) {
|
||||
continue;
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(dimIds)) {
|
||||
Set<Long> tmp = dimValueDictInfo.getDimIds();
|
||||
tmp.retainAll(dimIds);
|
||||
dimValueDictInfo.setDimIds(tmp);
|
||||
if (tmp.size() <= 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. extract
|
||||
Set<Long> dimIdList = dimValueDictInfo.getDimIds();
|
||||
for (Long dimId : dimIdList) {
|
||||
DictLatestTaskResp dictLatestTaskResp = new DictLatestTaskResp();
|
||||
if (!dimAndTaskPair.containsKey(dimId)) {
|
||||
BeanUtils.copyProperties(dimValueDictInfo, dictLatestTaskResp);
|
||||
dictLatestTaskResp.setDimId(dimId);
|
||||
} else {
|
||||
DictLatestTaskResp dictLatestTaskExist = dimAndTaskPair.get(dimId);
|
||||
if (dictLatestTaskExist.getCreatedAt().before(dimValueDictInfo.getCreatedAt())) {
|
||||
BeanUtils.copyProperties(dimValueDictInfo, dictLatestTaskResp);
|
||||
dictLatestTaskResp.setDimId(dimId);
|
||||
} else {
|
||||
dictLatestTaskResp = dictLatestTaskExist;
|
||||
}
|
||||
}
|
||||
dimAndTaskPair.put(dimId, dictLatestTaskResp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (dimAndTaskPair.size() >= 0 && !CollectionUtils.isEmpty(dimAndTaskPair.values())) {
|
||||
dimAndTaskPair.values().stream()
|
||||
.filter(v -> !v.getCommand().contains(DictUpdateMode.REALTIME_DELETE.name()))
|
||||
.forEach(v -> dictLatestTaskRespList.add(v));
|
||||
}
|
||||
|
||||
|
||||
return dictLatestTaskRespList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DimValueDictInfo> searchDictTaskList(DictTaskFilterReq filter, User user) {
|
||||
return dictRepository.searchDictTaskList(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictConfig getDictInfoByModelId(Long modelId) {
|
||||
return dictRepository.getDictInfoByModelId(modelId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ShowCaseResp;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.QueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatContextRepository;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatQueryRepository;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatRepository;
|
||||
import com.tencent.supersonic.chat.server.service.ChatService;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service("ChatService")
|
||||
@Primary
|
||||
@Slf4j
|
||||
public class ChatServiceImpl implements ChatService {
|
||||
|
||||
private ChatContextRepository chatContextRepository;
|
||||
private ChatRepository chatRepository;
|
||||
private ChatQueryRepository chatQueryRepository;
|
||||
|
||||
public ChatServiceImpl(ChatContextRepository chatContextRepository, ChatRepository chatRepository,
|
||||
ChatQueryRepository chatQueryRepository) {
|
||||
this.chatContextRepository = chatContextRepository;
|
||||
this.chatRepository = chatRepository;
|
||||
this.chatQueryRepository = chatQueryRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getContextModel(Integer chatId) {
|
||||
if (Objects.isNull(chatId)) {
|
||||
return null;
|
||||
}
|
||||
ChatContext chatContext = getOrCreateContext(chatId);
|
||||
if (Objects.isNull(chatContext)) {
|
||||
return null;
|
||||
}
|
||||
SemanticParseInfo originalSemanticParse = chatContext.getParseInfo();
|
||||
if (Objects.nonNull(originalSemanticParse) && Objects.nonNull(originalSemanticParse.getModel().getModelIds())) {
|
||||
return originalSemanticParse.getModel().getModelIds();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatContext getOrCreateContext(int chatId) {
|
||||
return chatContextRepository.getOrCreateContext(chatId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContext(ChatContext chatCtx) {
|
||||
log.debug("save ChatContext {}", chatCtx);
|
||||
chatContextRepository.updateContext(chatCtx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean addChat(User user, String chatName, Integer agentId) {
|
||||
ChatDO chatDO = new ChatDO();
|
||||
chatDO.setChatName(chatName);
|
||||
chatDO.setCreator(user.getName());
|
||||
chatDO.setCreateTime(getCurrentTime());
|
||||
chatDO.setIsDelete(0);
|
||||
chatDO.setLastTime(getCurrentTime());
|
||||
chatDO.setLastQuestion("Hello, welcome to using supersonic");
|
||||
chatDO.setIsTop(0);
|
||||
chatDO.setAgentId(agentId);
|
||||
return chatRepository.createChat(chatDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatDO> getAll(String userName, Integer agentId) {
|
||||
return chatRepository.getAll(userName, agentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateChatName(Long chatId, String chatName, String userName) {
|
||||
return chatRepository.updateChatName(chatId, chatName, getCurrentTime(), userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateFeedback(Integer id, Integer score, String feedback) {
|
||||
QueryDO intelligentQueryDO = new QueryDO();
|
||||
intelligentQueryDO.setId(id);
|
||||
intelligentQueryDO.setScore(score);
|
||||
intelligentQueryDO.setFeedback(feedback);
|
||||
return chatRepository.updateFeedback(intelligentQueryDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateChatIsTop(Long chatId, int isTop) {
|
||||
return chatRepository.updateConversionIsTop(chatId, isTop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteChat(Long chatId, String userName) {
|
||||
return chatRepository.deleteChat(chatId, userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<QueryResp> queryInfo(PageQueryInfoReq pageQueryInfoReq, long chatId) {
|
||||
PageInfo<QueryResp> queryRespPageInfo = chatQueryRepository.getChatQuery(pageQueryInfoReq, chatId);
|
||||
if (CollectionUtils.isEmpty(queryRespPageInfo.getList())) {
|
||||
return queryRespPageInfo;
|
||||
}
|
||||
fillParseInfo(queryRespPageInfo.getList());
|
||||
return queryRespPageInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResp getChatQuery(Long queryId) {
|
||||
return chatQueryRepository.getChatQuery(queryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShowCaseResp queryShowCase(PageQueryInfoReq pageQueryInfoReq, int agentId) {
|
||||
ShowCaseResp showCaseResp = new ShowCaseResp();
|
||||
showCaseResp.setCurrent(pageQueryInfoReq.getCurrent());
|
||||
showCaseResp.setPageSize(pageQueryInfoReq.getPageSize());
|
||||
List<QueryResp> queryResps = chatQueryRepository.queryShowCase(pageQueryInfoReq, agentId);
|
||||
if (CollectionUtils.isEmpty(queryResps)) {
|
||||
return showCaseResp;
|
||||
}
|
||||
queryResps.removeIf(queryResp -> {
|
||||
if (queryResp.getQueryResult() == null) {
|
||||
return true;
|
||||
}
|
||||
if (queryResp.getQueryResult().getResponse() != null) {
|
||||
return false;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(queryResp.getQueryResult().getQueryResults())) {
|
||||
return true;
|
||||
}
|
||||
Map<String, Object> data = queryResp.getQueryResult().getQueryResults().get(0);
|
||||
return CollectionUtils.isEmpty(data);
|
||||
});
|
||||
queryResps = new ArrayList<>(queryResps.stream()
|
||||
.collect(Collectors.toMap(QueryResp::getQueryText, Function.identity(),
|
||||
(existing, replacement) -> existing, LinkedHashMap::new)).values());
|
||||
fillParseInfo(queryResps);
|
||||
Map<Long, List<QueryResp>> showCaseMap = queryResps.stream()
|
||||
.collect(Collectors.groupingBy(QueryResp::getChatId));
|
||||
showCaseResp.setShowCaseMap(showCaseMap);
|
||||
return showCaseResp;
|
||||
}
|
||||
|
||||
private void fillParseInfo(List<QueryResp> queryResps) {
|
||||
List<Long> queryIds = queryResps.stream()
|
||||
.map(QueryResp::getQuestionId).collect(Collectors.toList());
|
||||
List<ChatParseDO> chatParseDOs = chatQueryRepository.getParseInfoList(queryIds);
|
||||
if (CollectionUtils.isEmpty(chatParseDOs)) {
|
||||
return;
|
||||
}
|
||||
Map<Long, List<ChatParseDO>> chatParseMap = chatParseDOs.stream()
|
||||
.collect(Collectors.groupingBy(ChatParseDO::getQuestionId));
|
||||
for (QueryResp queryResp : queryResps) {
|
||||
List<ChatParseDO> chatParseDOList = chatParseMap.get(queryResp.getQuestionId());
|
||||
if (CollectionUtils.isEmpty(chatParseDOList)) {
|
||||
continue;
|
||||
}
|
||||
List<SemanticParseInfo> parseInfos = chatParseDOList.stream().map(chatParseDO ->
|
||||
JsonUtil.toObject(chatParseDO.getParseInfo(), SemanticParseInfo.class))
|
||||
.sorted(Comparator.comparingDouble(SemanticParseInfo::getScore).reversed())
|
||||
.collect(Collectors.toList());
|
||||
queryResp.setParseInfos(parseInfos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateQuery(Long questionId, int parseId, QueryResult queryResult, ChatContext chatCtx) {
|
||||
//The history record only retains the query result of the first parse
|
||||
if (parseId > 1) {
|
||||
return;
|
||||
}
|
||||
ChatQueryDO chatQueryDO = new ChatQueryDO();
|
||||
chatQueryDO.setQuestionId(questionId);
|
||||
chatQueryDO.setQueryResult(JsonUtil.toString(queryResult));
|
||||
chatQueryDO.setQueryState(1);
|
||||
updateQuery(chatQueryDO);
|
||||
chatRepository.updateLastQuestion(chatCtx.getChatId().longValue(),
|
||||
chatCtx.getQueryText(), getCurrentTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateQuery(ChatQueryDO chatQueryDO) {
|
||||
return chatQueryRepository.updateChatQuery(chatQueryDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatParseDO> batchAddParse(ChatContext chatCtx, QueryReq queryReq, ParseResp parseResult) {
|
||||
List<SemanticParseInfo> candidateParses = parseResult.getSelectedParses();
|
||||
return chatQueryRepository.batchSaveParseInfo(chatCtx, queryReq, parseResult, candidateParses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatQueryDO getLastQuery(long chatId) {
|
||||
return chatQueryRepository.getLastChatQuery(chatId);
|
||||
}
|
||||
|
||||
private String getCurrentTime() {
|
||||
SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return tempDate.format(new java.util.Date());
|
||||
}
|
||||
|
||||
public ChatParseDO getParseInfo(Long questionId, int parseId) {
|
||||
return chatQueryRepository.getParseInfo(questionId, parseId);
|
||||
}
|
||||
|
||||
public Boolean deleteChatQuery(Long questionId) {
|
||||
return chatQueryRepository.deleteChatQuery(questionId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatAggConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigBaseReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigEditReqReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatDetailConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.Entity;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ItemNameVisibilityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ItemVisibility;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatAggRichConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatDefaultRichConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatDetailRichConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityRichInfoResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ItemVisibilityInfo;
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfig;
|
||||
import com.tencent.supersonic.chat.server.util.ChatConfigHelper;
|
||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.server.util.VisibilityEvent;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.ChatConfigRepository;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import com.tencent.supersonic.chat.server.service.SemanticService;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.headless.api.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.headless.api.response.DimensionResp;
|
||||
import com.tencent.supersonic.headless.api.response.MetricResp;
|
||||
import com.tencent.supersonic.headless.server.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.headless.server.service.DimensionService;
|
||||
import com.tencent.supersonic.headless.server.service.MetricService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ConfigServiceImpl implements ConfigService {
|
||||
|
||||
private final ChatConfigRepository chatConfigRepository;
|
||||
private final ChatConfigHelper chatConfigHelper;
|
||||
private final DimensionService dimensionService;
|
||||
private final MetricService metricService;
|
||||
@Autowired
|
||||
private SemanticService semanticService;
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
private SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
|
||||
|
||||
public ConfigServiceImpl(ChatConfigRepository chatConfigRepository,
|
||||
ChatConfigHelper chatConfigHelper,
|
||||
DimensionService dimensionService,
|
||||
MetricService metricService) {
|
||||
this.chatConfigRepository = chatConfigRepository;
|
||||
this.chatConfigHelper = chatConfigHelper;
|
||||
this.dimensionService = dimensionService;
|
||||
this.metricService = metricService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long addConfig(ChatConfigBaseReq configBaseCmd, User user) {
|
||||
log.info("[create model extend] object:{}", JsonUtil.toString(configBaseCmd, true));
|
||||
duplicateCheck(configBaseCmd.getModelId());
|
||||
ChatConfig chaConfig = chatConfigHelper.newChatConfig(configBaseCmd, user);
|
||||
Long id = chatConfigRepository.createConfig(chaConfig);
|
||||
applicationEventPublisher.publishEvent(new VisibilityEvent(this, chaConfig));
|
||||
return id;
|
||||
}
|
||||
|
||||
private void duplicateCheck(Long modelId) {
|
||||
ChatConfigFilter filter = new ChatConfigFilter();
|
||||
filter.setModelId(modelId);
|
||||
List<ChatConfigResp> chaConfigDescList = chatConfigRepository.getChatConfig(filter);
|
||||
if (!CollectionUtils.isEmpty(chaConfigDescList)) {
|
||||
throw new RuntimeException("chat config existed, no need to add repeatedly");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long editConfig(ChatConfigEditReqReq configEditCmd, User user) {
|
||||
log.info("[edit model extend] object:{}", JsonUtil.toString(configEditCmd, true));
|
||||
if (Objects.isNull(configEditCmd) || Objects.isNull(configEditCmd.getId()) && Objects.isNull(
|
||||
configEditCmd.getModelId())) {
|
||||
throw new RuntimeException("editConfig, id and modelId are not allowed to be empty at the same time");
|
||||
}
|
||||
ChatConfig chaConfig = chatConfigHelper.editChatConfig(configEditCmd, user);
|
||||
chatConfigRepository.updateConfig(chaConfig);
|
||||
applicationEventPublisher.publishEvent(new VisibilityEvent(this, chaConfig));
|
||||
return configEditCmd.getId();
|
||||
}
|
||||
|
||||
public ItemNameVisibilityInfo getVisibilityByModelId(Long modelId) {
|
||||
ChatConfigResp chatConfigResp = fetchConfigByModelId(modelId);
|
||||
ChatConfig chatConfig = new ChatConfig();
|
||||
chatConfig.setModelId(modelId);
|
||||
chatConfig.setChatAggConfig(chatConfigResp.getChatAggConfig());
|
||||
chatConfig.setChatDetailConfig(chatConfigResp.getChatDetailConfig());
|
||||
ItemNameVisibilityInfo itemNameVisibility = getItemNameVisibility(chatConfig);
|
||||
return itemNameVisibility;
|
||||
}
|
||||
|
||||
public ItemNameVisibilityInfo getItemNameVisibility(ChatConfig chatConfig) {
|
||||
Long modelId = chatConfig.getModelId();
|
||||
|
||||
List<Long> blackDimIdList = new ArrayList<>();
|
||||
if (Objects.nonNull(chatConfig.getChatAggConfig()) && Objects.nonNull(chatConfig.getChatAggConfig())) {
|
||||
blackDimIdList.addAll(chatConfig.getChatAggConfig().getVisibility().getBlackDimIdList());
|
||||
}
|
||||
if (Objects.nonNull(chatConfig.getChatDetailConfig()) && Objects.nonNull(chatConfig.getChatDetailConfig())) {
|
||||
blackDimIdList.addAll(chatConfig.getChatDetailConfig().getVisibility().getBlackDimIdList());
|
||||
}
|
||||
List<Long> filterDimIdList = blackDimIdList.stream().distinct().collect(Collectors.toList());
|
||||
|
||||
List<Long> blackMetricIdList = new ArrayList<>();
|
||||
if (Objects.nonNull(chatConfig.getChatAggConfig()) && Objects.nonNull(chatConfig.getChatAggConfig())) {
|
||||
blackMetricIdList.addAll(chatConfig.getChatAggConfig().getVisibility().getBlackMetricIdList());
|
||||
}
|
||||
if (Objects.nonNull(chatConfig.getChatDetailConfig()) && Objects.nonNull(chatConfig.getChatDetailConfig())) {
|
||||
blackMetricIdList.addAll(chatConfig.getChatDetailConfig().getVisibility().getBlackMetricIdList());
|
||||
}
|
||||
List<Long> filterMetricIdList = blackMetricIdList.stream().distinct().collect(Collectors.toList());
|
||||
|
||||
ItemNameVisibilityInfo itemNameVisibility = new ItemNameVisibilityInfo();
|
||||
MetaFilter metaFilter = new MetaFilter();
|
||||
metaFilter.setModelIds(Lists.newArrayList(modelId));
|
||||
if (!CollectionUtils.isEmpty(blackDimIdList)) {
|
||||
List<DimensionResp> dimensionRespList = dimensionService.getDimensions(metaFilter);
|
||||
List<String> blackDimNameList = dimensionRespList.stream().filter(o -> filterDimIdList.contains(o.getId()))
|
||||
.map(SchemaItem::getName).collect(Collectors.toList());
|
||||
itemNameVisibility.setBlackDimNameList(blackDimNameList);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(blackMetricIdList)) {
|
||||
|
||||
List<MetricResp> metricRespList = metricService.getMetrics(metaFilter);
|
||||
List<String> blackMetricList = metricRespList.stream().filter(o -> filterMetricIdList.contains(o.getId()))
|
||||
.map(SchemaItem::getName).collect(Collectors.toList());
|
||||
itemNameVisibility.setBlackMetricNameList(blackMetricList);
|
||||
}
|
||||
return itemNameVisibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatConfigResp> search(ChatConfigFilter filter, User user) {
|
||||
log.info("[search model extend] object:{}", JsonUtil.toString(filter, true));
|
||||
List<ChatConfigResp> chaConfigDescList = chatConfigRepository.getChatConfig(filter);
|
||||
return chaConfigDescList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatConfigResp fetchConfigByModelId(Long modelId) {
|
||||
return chatConfigRepository.getConfigByModelId(modelId);
|
||||
}
|
||||
|
||||
private ItemVisibilityInfo fetchVisibilityDescByConfig(ItemVisibility visibility,
|
||||
ModelSchema modelSchema) {
|
||||
ItemVisibilityInfo itemVisibilityDesc = new ItemVisibilityInfo();
|
||||
|
||||
List<Long> dimIdAllList = chatConfigHelper.generateAllDimIdList(modelSchema);
|
||||
List<Long> metricIdAllList = chatConfigHelper.generateAllMetricIdList(modelSchema);
|
||||
|
||||
List<Long> blackDimIdList = new ArrayList<>();
|
||||
List<Long> blackMetricIdList = new ArrayList<>();
|
||||
if (Objects.nonNull(visibility)) {
|
||||
if (!CollectionUtils.isEmpty(visibility.getBlackDimIdList())) {
|
||||
blackDimIdList.addAll(visibility.getBlackDimIdList());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(visibility.getBlackMetricIdList())) {
|
||||
blackMetricIdList.addAll(visibility.getBlackMetricIdList());
|
||||
}
|
||||
}
|
||||
List<Long> whiteMetricIdList = metricIdAllList.stream()
|
||||
.filter(id -> !blackMetricIdList.contains(id) && metricIdAllList.contains(id))
|
||||
.collect(Collectors.toList());
|
||||
List<Long> whiteDimIdList = dimIdAllList.stream()
|
||||
.filter(id -> !blackDimIdList.contains(id) && dimIdAllList.contains(id))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
itemVisibilityDesc.setBlackDimIdList(blackDimIdList);
|
||||
itemVisibilityDesc.setBlackMetricIdList(blackMetricIdList);
|
||||
itemVisibilityDesc.setWhiteDimIdList(Objects.isNull(whiteDimIdList) ? new ArrayList<>() : whiteDimIdList);
|
||||
itemVisibilityDesc.setWhiteMetricIdList(
|
||||
Objects.isNull(whiteMetricIdList) ? new ArrayList<>() : whiteMetricIdList);
|
||||
|
||||
return itemVisibilityDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatConfigRichResp getConfigRichInfo(Long modelId) {
|
||||
ChatConfigRichResp chatConfigRich = new ChatConfigRichResp();
|
||||
ChatConfigResp chatConfigResp = chatConfigRepository.getConfigByModelId(modelId);
|
||||
if (Objects.isNull(chatConfigResp)) {
|
||||
log.info("there is no chatConfigDesc for modelId:{}", modelId);
|
||||
return chatConfigRich;
|
||||
}
|
||||
BeanUtils.copyProperties(chatConfigResp, chatConfigRich);
|
||||
|
||||
ModelSchema modelSchema = semanticService.getModelSchema(modelId);
|
||||
if (modelSchema == null) {
|
||||
return chatConfigRich;
|
||||
}
|
||||
chatConfigRich.setBizName(modelSchema.getModel().getBizName());
|
||||
chatConfigRich.setModelName(modelSchema.getModel().getName());
|
||||
|
||||
chatConfigRich.setChatAggRichConfig(fillChatAggRichConfig(modelSchema, chatConfigResp));
|
||||
chatConfigRich.setChatDetailRichConfig(fillChatDetailRichConfig(modelSchema, chatConfigRich, chatConfigResp));
|
||||
|
||||
return chatConfigRich;
|
||||
}
|
||||
|
||||
private ChatDetailRichConfigResp fillChatDetailRichConfig(ModelSchema modelSchema,
|
||||
ChatConfigRichResp chatConfigRich,
|
||||
ChatConfigResp chatConfigResp) {
|
||||
if (Objects.isNull(chatConfigResp) || Objects.isNull(chatConfigResp.getChatDetailConfig())) {
|
||||
return null;
|
||||
}
|
||||
ChatDetailRichConfigResp detailRichConfig = new ChatDetailRichConfigResp();
|
||||
ChatDetailConfigReq chatDetailConfig = chatConfigResp.getChatDetailConfig();
|
||||
ItemVisibilityInfo itemVisibilityInfo = fetchVisibilityDescByConfig(
|
||||
chatDetailConfig.getVisibility(), modelSchema);
|
||||
detailRichConfig.setVisibility(itemVisibilityInfo);
|
||||
detailRichConfig.setKnowledgeInfos(fillKnowledgeBizName(chatDetailConfig.getKnowledgeInfos(), modelSchema));
|
||||
detailRichConfig.setGlobalKnowledgeConfig(chatDetailConfig.getGlobalKnowledgeConfig());
|
||||
detailRichConfig.setChatDefaultConfig(fetchDefaultConfig(chatDetailConfig.getChatDefaultConfig(),
|
||||
modelSchema, itemVisibilityInfo));
|
||||
|
||||
return detailRichConfig;
|
||||
}
|
||||
|
||||
private EntityRichInfoResp generateRichEntity(Entity entity, ModelSchema modelSchema) {
|
||||
EntityRichInfoResp entityRichInfo = new EntityRichInfoResp();
|
||||
if (Objects.isNull(entity) || Objects.isNull(entity.getEntityId())) {
|
||||
return entityRichInfo;
|
||||
}
|
||||
BeanUtils.copyProperties(entity, entityRichInfo);
|
||||
Map<Long, SchemaElement> dimIdAndRespPair = modelSchema.getDimensions().stream()
|
||||
.collect(Collectors.toMap(SchemaElement::getId, Function.identity(), (k1, k2) -> k1));
|
||||
|
||||
entityRichInfo.setDimItem(dimIdAndRespPair.get(entity.getEntityId()));
|
||||
return entityRichInfo;
|
||||
}
|
||||
|
||||
private ChatAggRichConfigResp fillChatAggRichConfig(ModelSchema modelSchema, ChatConfigResp chatConfigResp) {
|
||||
if (Objects.isNull(chatConfigResp) || Objects.isNull(chatConfigResp.getChatAggConfig())) {
|
||||
return null;
|
||||
}
|
||||
ChatAggConfigReq chatAggConfig = chatConfigResp.getChatAggConfig();
|
||||
ChatAggRichConfigResp chatAggRichConfig = new ChatAggRichConfigResp();
|
||||
ItemVisibilityInfo itemVisibilityInfo = fetchVisibilityDescByConfig(chatAggConfig.getVisibility(), modelSchema);
|
||||
chatAggRichConfig.setVisibility(itemVisibilityInfo);
|
||||
chatAggRichConfig.setKnowledgeInfos(fillKnowledgeBizName(chatAggConfig.getKnowledgeInfos(), modelSchema));
|
||||
chatAggRichConfig.setGlobalKnowledgeConfig(chatAggConfig.getGlobalKnowledgeConfig());
|
||||
chatAggRichConfig.setChatDefaultConfig(fetchDefaultConfig(chatAggConfig.getChatDefaultConfig(),
|
||||
modelSchema, itemVisibilityInfo));
|
||||
|
||||
return chatAggRichConfig;
|
||||
}
|
||||
|
||||
private ChatDefaultRichConfigResp fetchDefaultConfig(ChatDefaultConfigReq chatDefaultConfig,
|
||||
ModelSchema modelSchema,
|
||||
ItemVisibilityInfo itemVisibilityInfo) {
|
||||
ChatDefaultRichConfigResp defaultRichConfig = new ChatDefaultRichConfigResp();
|
||||
if (Objects.isNull(chatDefaultConfig)) {
|
||||
return defaultRichConfig;
|
||||
}
|
||||
BeanUtils.copyProperties(chatDefaultConfig, defaultRichConfig);
|
||||
Map<Long, SchemaElement> dimIdAndRespPair = modelSchema.getDimensions().stream()
|
||||
.collect(Collectors.toMap(SchemaElement::getId, Function.identity(), (k1, k2) -> k1));
|
||||
|
||||
Map<Long, SchemaElement> metricIdAndRespPair = modelSchema.getMetrics().stream()
|
||||
.collect(Collectors.toMap(SchemaElement::getId, Function.identity(), (k1, k2) -> k1));
|
||||
|
||||
List<SchemaElement> dimensions = new ArrayList<>();
|
||||
List<SchemaElement> metrics = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(chatDefaultConfig.getDimensionIds())) {
|
||||
chatDefaultConfig.getDimensionIds().stream()
|
||||
.filter(dimId -> dimIdAndRespPair.containsKey(dimId)
|
||||
&& itemVisibilityInfo.getWhiteDimIdList().contains(dimId))
|
||||
.forEach(dimId -> {
|
||||
SchemaElement dimSchemaResp = dimIdAndRespPair.get(dimId);
|
||||
if (Objects.nonNull(dimSchemaResp)) {
|
||||
SchemaElement dimSchema = new SchemaElement();
|
||||
BeanUtils.copyProperties(dimSchemaResp, dimSchema);
|
||||
dimensions.add(dimSchema);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(chatDefaultConfig.getMetricIds())) {
|
||||
chatDefaultConfig.getMetricIds().stream()
|
||||
.filter(metricId -> metricIdAndRespPair.containsKey(metricId)
|
||||
&& itemVisibilityInfo.getWhiteMetricIdList().contains(metricId))
|
||||
.forEach(metricId -> {
|
||||
SchemaElement metricSchemaResp = metricIdAndRespPair.get(metricId);
|
||||
if (Objects.nonNull(metricSchemaResp)) {
|
||||
SchemaElement metricSchema = new SchemaElement();
|
||||
BeanUtils.copyProperties(metricSchemaResp, metricSchema);
|
||||
metrics.add(metricSchema);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
defaultRichConfig.setDimensions(dimensions);
|
||||
defaultRichConfig.setMetrics(metrics);
|
||||
return defaultRichConfig;
|
||||
}
|
||||
|
||||
private List<KnowledgeInfoReq> fillKnowledgeBizName(List<KnowledgeInfoReq> knowledgeInfos,
|
||||
ModelSchema modelSchema) {
|
||||
if (CollectionUtils.isEmpty(knowledgeInfos)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<Long, SchemaElement> dimIdAndRespPair = modelSchema.getDimensions().stream()
|
||||
.collect(Collectors.toMap(SchemaElement::getId, Function.identity(), (k1, k2) -> k1));
|
||||
knowledgeInfos.stream().forEach(knowledgeInfo -> {
|
||||
if (Objects.nonNull(knowledgeInfo)) {
|
||||
SchemaElement dimSchemaResp = dimIdAndRespPair.get(knowledgeInfo.getItemId());
|
||||
if (Objects.nonNull(dimSchemaResp)) {
|
||||
knowledgeInfo.setBizName(dimSchemaResp.getBizName());
|
||||
}
|
||||
}
|
||||
});
|
||||
return knowledgeInfos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatConfigRichResp> getAllChatRichConfig() {
|
||||
List<ChatConfigRichResp> chatConfigRichInfoList = new ArrayList<>();
|
||||
List<ModelSchema> modelSchemas = semanticInterpreter.getModelSchema();
|
||||
modelSchemas.stream().forEach(modelSchema -> {
|
||||
ChatConfigRichResp chatConfigRichInfo = getConfigRichInfo(modelSchema.getModel().getId());
|
||||
if (Objects.nonNull(chatConfigRichInfo)) {
|
||||
chatConfigRichInfoList.add(chatConfigRichInfo);
|
||||
}
|
||||
});
|
||||
return chatConfigRichInfoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, ChatConfigRichResp> getModelIdToChatRichConfig() {
|
||||
List<ChatConfigRichResp> allChatRichConfig = getAllChatRichConfig();
|
||||
return allChatRichConfig.stream()
|
||||
.collect(Collectors.toMap(ChatConfigRichResp::getModelId, value -> value, (k1, k2) -> k1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictWord;
|
||||
import com.tencent.supersonic.chat.core.knowledge.SearchService;
|
||||
import com.tencent.supersonic.chat.core.utils.HanlpHelper;
|
||||
import com.tencent.supersonic.chat.server.service.KnowledgeService;
|
||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class KnowledgeServiceImpl implements KnowledgeService {
|
||||
|
||||
public void updateSemanticKnowledge(List<DictWord> natures) {
|
||||
|
||||
List<DictWord> prefixes = natures.stream()
|
||||
.filter(entry -> !entry.getNatureWithFrequency().contains(DictWordType.SUFFIX.getType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (DictWord nature : prefixes) {
|
||||
HanlpHelper.addToCustomDictionary(nature);
|
||||
}
|
||||
|
||||
List<DictWord> suffixes = natures.stream()
|
||||
.filter(entry -> entry.getNatureWithFrequency().contains(DictWordType.SUFFIX.getType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
SearchService.loadSuffix(suffixes);
|
||||
}
|
||||
|
||||
public void reloadAllData(List<DictWord> natures) {
|
||||
// 1. reload custom knowledge
|
||||
try {
|
||||
HanlpHelper.reloadCustomDictionary();
|
||||
} catch (Exception e) {
|
||||
log.error("reloadCustomDictionary error", e);
|
||||
}
|
||||
|
||||
// 2. update online knowledge
|
||||
updateOnlineKnowledge(natures);
|
||||
}
|
||||
|
||||
public void updateOnlineKnowledge(List<DictWord> natures) {
|
||||
try {
|
||||
updateSemanticKnowledge(natures);
|
||||
} catch (Exception e) {
|
||||
log.error("updateSemanticKnowledge error", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.PluginQueryReq;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.core.plugin.Plugin;
|
||||
import com.tencent.supersonic.chat.core.plugin.PluginParseConfig;
|
||||
import com.tencent.supersonic.chat.core.plugin.event.PluginAddEvent;
|
||||
import com.tencent.supersonic.chat.core.plugin.event.PluginDelEvent;
|
||||
import com.tencent.supersonic.chat.core.plugin.event.PluginUpdateEvent;
|
||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.PluginDOExample;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.PluginRepository;
|
||||
import com.tencent.supersonic.chat.server.service.PluginService;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.headless.api.response.ModelResp;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PluginServiceImpl implements PluginService {
|
||||
|
||||
private PluginRepository pluginRepository;
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
public PluginServiceImpl(PluginRepository pluginRepository,
|
||||
ApplicationEventPublisher publisher) {
|
||||
this.pluginRepository = pluginRepository;
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void createPlugin(Plugin plugin, User user) {
|
||||
PluginDO pluginDO = convert(plugin, user);
|
||||
pluginRepository.createPlugin(pluginDO);
|
||||
//compatible with H2 db
|
||||
List<Plugin> plugins = getPluginList();
|
||||
publisher.publishEvent(new PluginAddEvent(this, plugins.get(plugins.size() - 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePlugin(Plugin plugin, User user) {
|
||||
Long id = plugin.getId();
|
||||
PluginDO pluginDO = pluginRepository.getPlugin(id);
|
||||
Plugin oldPlugin = convert(pluginDO);
|
||||
convert(plugin, pluginDO, user);
|
||||
pluginRepository.updatePlugin(pluginDO);
|
||||
publisher.publishEvent(new PluginUpdateEvent(this, oldPlugin, plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePlugin(Long id) {
|
||||
PluginDO pluginDO = pluginRepository.getPlugin(id);
|
||||
if (pluginDO != null) {
|
||||
pluginRepository.deletePlugin(id);
|
||||
publisher.publishEvent(new PluginDelEvent(this, convert(pluginDO)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plugin> getPluginList() {
|
||||
List<Plugin> plugins = Lists.newArrayList();
|
||||
List<PluginDO> pluginDOS = pluginRepository.getPlugins();
|
||||
if (CollectionUtils.isEmpty(pluginDOS)) {
|
||||
return plugins;
|
||||
}
|
||||
return pluginDOS.stream().map(this::convert).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plugin> fetchPluginDOs(String queryText, String type) {
|
||||
List<PluginDO> pluginDOS = pluginRepository.fetchPluginDOs(queryText, type);
|
||||
return convertList(pluginDOS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plugin> query(PluginQueryReq pluginQueryReq) {
|
||||
PluginDOExample pluginDOExample = new PluginDOExample();
|
||||
pluginDOExample.createCriteria();
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getType())) {
|
||||
pluginDOExample.getOredCriteria().get(0).andTypeEqualTo(pluginQueryReq.getType());
|
||||
}
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getModel())) {
|
||||
pluginDOExample.getOredCriteria().get(0).andModelLike('%' + pluginQueryReq.getModel() + '%');
|
||||
}
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getParseMode())) {
|
||||
pluginDOExample.getOredCriteria().get(0).andParseModeEqualTo(pluginQueryReq.getParseMode());
|
||||
}
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getName())) {
|
||||
pluginDOExample.getOredCriteria().get(0).andNameLike('%' + pluginQueryReq.getName() + '%');
|
||||
}
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getPattern())) {
|
||||
pluginDOExample.getOredCriteria().get(0).andPatternLike('%' + pluginQueryReq.getPattern() + '%');
|
||||
}
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getCreatedBy())) {
|
||||
pluginDOExample.getOredCriteria().get(0).andCreatedByEqualTo(pluginQueryReq.getCreatedBy());
|
||||
}
|
||||
List<PluginDO> pluginDOS = pluginRepository.query(pluginDOExample);
|
||||
if (StringUtils.isNotBlank(pluginQueryReq.getPattern())) {
|
||||
pluginDOS = pluginDOS.stream().filter(pluginDO ->
|
||||
pluginDO.getPattern().contains(pluginQueryReq.getPattern())
|
||||
|| (pluginDO.getName() != null
|
||||
&& pluginDO.getName().contains(pluginQueryReq.getPattern())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return convertList(pluginDOS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Plugin> getPluginByName(String name) {
|
||||
log.info("name:{}", name);
|
||||
return getPluginList().stream()
|
||||
.filter(plugin -> {
|
||||
PluginParseConfig functionCallConfig = getPluginParseConfig(plugin);
|
||||
if (functionCallConfig == null) {
|
||||
return false;
|
||||
}
|
||||
return functionCallConfig.getName().equalsIgnoreCase(name);
|
||||
})
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private PluginParseConfig getPluginParseConfig(Plugin plugin) {
|
||||
if (StringUtils.isBlank(plugin.getParseModeConfig())) {
|
||||
return null;
|
||||
}
|
||||
PluginParseConfig functionCallConfig = JsonUtil.toObject(
|
||||
plugin.getParseModeConfig(), PluginParseConfig.class);
|
||||
if (Objects.isNull(functionCallConfig) || StringUtils.isEmpty(functionCallConfig.getName())) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isBlank(functionCallConfig.getName())) {
|
||||
return null;
|
||||
}
|
||||
return functionCallConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plugin> queryWithAuthCheck(PluginQueryReq pluginQueryReq, User user) {
|
||||
return authCheck(query(pluginQueryReq), user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Plugin> getNameToPlugin() {
|
||||
List<Plugin> pluginList = getPluginList();
|
||||
|
||||
return pluginList.stream()
|
||||
.filter(plugin -> {
|
||||
PluginParseConfig functionCallConfig = getPluginParseConfig(plugin);
|
||||
if (functionCallConfig == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.collect(Collectors.toMap(a -> {
|
||||
PluginParseConfig functionCallConfig = JsonUtil.toObject(
|
||||
a.getParseModeConfig(), PluginParseConfig.class);
|
||||
return functionCallConfig.getName();
|
||||
}, a -> a, (k1, k2) -> k1));
|
||||
}
|
||||
|
||||
private List<Plugin> authCheck(List<Plugin> plugins, User user) {
|
||||
SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
List<Long> modelIdAuthorized = semanticInterpreter.getModelList(AuthType.ADMIN, null, user).stream()
|
||||
.map(ModelResp::getId).collect(Collectors.toList());
|
||||
plugins = plugins.stream().filter(plugin -> {
|
||||
if (CollectionUtils.isEmpty(plugin.getModelList()) || plugin.isContainsAllModel()) {
|
||||
return true;
|
||||
}
|
||||
for (Long modelId : plugin.getModelList()) {
|
||||
if (modelIdAuthorized.contains(modelId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).collect(Collectors.toList());
|
||||
return plugins;
|
||||
}
|
||||
|
||||
public Plugin convert(PluginDO pluginDO) {
|
||||
Plugin plugin = new Plugin();
|
||||
BeanUtils.copyProperties(pluginDO, plugin);
|
||||
if (StringUtils.isNotBlank(pluginDO.getModel())) {
|
||||
plugin.setModelList(Arrays.stream(pluginDO.getModel().split(","))
|
||||
.map(Long::parseLong).collect(Collectors.toList()));
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public PluginDO convert(Plugin plugin, User user) {
|
||||
PluginDO pluginDO = new PluginDO();
|
||||
BeanUtils.copyProperties(plugin, pluginDO);
|
||||
pluginDO.setCreatedAt(new Date());
|
||||
pluginDO.setCreatedBy(user.getName());
|
||||
pluginDO.setUpdatedAt(new Date());
|
||||
pluginDO.setUpdatedBy(user.getName());
|
||||
pluginDO.setModel(StringUtils.join(plugin.getModelList(), ","));
|
||||
return pluginDO;
|
||||
}
|
||||
|
||||
public PluginDO convert(Plugin plugin, PluginDO pluginDO, User user) {
|
||||
BeanUtils.copyProperties(plugin, pluginDO);
|
||||
pluginDO.setUpdatedAt(new Date());
|
||||
pluginDO.setUpdatedBy(user.getName());
|
||||
pluginDO.setModel(StringUtils.join(plugin.getModelList(), ","));
|
||||
return pluginDO;
|
||||
}
|
||||
|
||||
public List<Plugin> convertList(List<PluginDO> pluginDOS) {
|
||||
if (!CollectionUtils.isEmpty(pluginDOS)) {
|
||||
return pluginDOS.stream().map(this::convert).collect(Collectors.toList());
|
||||
}
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,700 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaMapInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticParseInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.DimensionValueReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ExecuteQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryDataReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilters;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.SimilarQueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.EntityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ParseResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.QueryState;
|
||||
import com.tencent.supersonic.chat.core.agent.Agent;
|
||||
import com.tencent.supersonic.chat.core.corrector.SemanticCorrector;
|
||||
import com.tencent.supersonic.chat.core.knowledge.HanlpMapResult;
|
||||
import com.tencent.supersonic.chat.core.knowledge.SearchService;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.core.mapper.SchemaMapper;
|
||||
import com.tencent.supersonic.chat.core.parser.SemanticParser;
|
||||
import com.tencent.supersonic.chat.core.plugin.Plugin;
|
||||
import com.tencent.supersonic.chat.core.pojo.ChatContext;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.core.query.QueryManager;
|
||||
import com.tencent.supersonic.chat.core.query.SemanticQuery;
|
||||
import com.tencent.supersonic.chat.core.query.llm.s2sql.LLMSqlQuery;
|
||||
import com.tencent.supersonic.chat.core.query.rule.RuleSemanticQuery;
|
||||
import com.tencent.supersonic.chat.core.utils.HanlpHelper;
|
||||
import com.tencent.supersonic.chat.core.utils.NatureHelper;
|
||||
import com.tencent.supersonic.chat.core.utils.SimilarQueryManager;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.CostType;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.StatisticsDO;
|
||||
import com.tencent.supersonic.chat.server.processor.execute.ExecuteResultProcessor;
|
||||
import com.tencent.supersonic.chat.server.processor.parse.ParseResultProcessor;
|
||||
import com.tencent.supersonic.chat.server.service.AgentService;
|
||||
import com.tencent.supersonic.chat.server.service.ChatService;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import com.tencent.supersonic.chat.server.service.PluginService;
|
||||
import com.tencent.supersonic.chat.server.service.QueryService;
|
||||
import com.tencent.supersonic.chat.server.service.SemanticService;
|
||||
import com.tencent.supersonic.chat.server.service.StatisticsService;
|
||||
import com.tencent.supersonic.chat.server.service.TimeCost;
|
||||
import com.tencent.supersonic.chat.server.util.ComponentFactory;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.DateUtils;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.FieldExpression;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserAddHelper;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserRemoveHelper;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserReplaceHelper;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||
import com.tencent.supersonic.headless.api.request.QueryStructReq;
|
||||
import com.tencent.supersonic.headless.api.response.QueryResultWithSchemaResp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
|
||||
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
|
||||
import net.sf.jsqlparser.expression.operators.relational.InExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import org.apache.calcite.sql.parser.SqlParseException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Component("chatQueryService")
|
||||
@Primary
|
||||
@Slf4j
|
||||
public class QueryServiceImpl implements QueryService {
|
||||
|
||||
@Autowired
|
||||
private ChatService chatService;
|
||||
@Autowired
|
||||
private StatisticsService statisticsService;
|
||||
@Autowired
|
||||
private SimilarQueryManager similarQueryManager;
|
||||
@Autowired
|
||||
private SchemaService schemaService;
|
||||
@Autowired
|
||||
private AgentService agentService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private PluginService pluginService;
|
||||
|
||||
@Value("${time.threshold: 100}")
|
||||
private Integer timeThreshold;
|
||||
|
||||
private List<SchemaMapper> schemaMappers = ComponentFactory.getSchemaMappers();
|
||||
private List<SemanticParser> semanticParsers = ComponentFactory.getSemanticParsers();
|
||||
private List<ParseResultProcessor> parseProcessors = ComponentFactory.getParseProcessors();
|
||||
private List<ExecuteResultProcessor> executeProcessors = ComponentFactory.getExecuteProcessors();
|
||||
private List<SemanticCorrector> semanticCorrectors = ComponentFactory.getSemanticCorrectors();
|
||||
|
||||
@Override
|
||||
public ParseResp performParsing(QueryReq queryReq) {
|
||||
ParseResp parseResult = new ParseResp();
|
||||
// build queryContext and chatContext
|
||||
QueryContext queryCtx = buildQueryContext(queryReq);
|
||||
|
||||
// in order to support multi-turn conversation, chat context is needed
|
||||
ChatContext chatCtx = chatService.getOrCreateContext(queryReq.getChatId());
|
||||
List<StatisticsDO> timeCostDOList = new ArrayList<>();
|
||||
|
||||
// 1. mapper
|
||||
schemaMappers.forEach(mapper -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
mapper.map(queryCtx);
|
||||
timeCostDOList.add(StatisticsDO.builder().cost((int) (System.currentTimeMillis() - startTime))
|
||||
.interfaceName(mapper.getClass().getSimpleName()).type(CostType.MAPPER.getType()).build());
|
||||
});
|
||||
|
||||
// 2. parser
|
||||
semanticParsers.forEach(parser -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
parser.parse(queryCtx, chatCtx);
|
||||
timeCostDOList.add(StatisticsDO.builder().cost((int) (System.currentTimeMillis() - startTime))
|
||||
.interfaceName(parser.getClass().getSimpleName()).type(CostType.PARSER.getType()).build());
|
||||
log.info("{} result:{}", parser.getClass().getSimpleName(), JsonUtil.toString(queryCtx));
|
||||
});
|
||||
|
||||
// 3. corrector
|
||||
List<SemanticQuery> candidateQueries = queryCtx.getCandidateQueries();
|
||||
if (CollectionUtils.isNotEmpty(candidateQueries)) {
|
||||
for (SemanticQuery semanticQuery : candidateQueries) {
|
||||
// the rules are not being corrected.
|
||||
if (semanticQuery instanceof RuleSemanticQuery) {
|
||||
continue;
|
||||
}
|
||||
semanticCorrectors.forEach(corrector -> {
|
||||
corrector.correct(queryCtx, semanticQuery.getParseInfo());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 4. processor
|
||||
parseProcessors.forEach(processor -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
processor.process(parseResult, queryCtx, chatCtx);
|
||||
timeCostDOList.add(StatisticsDO.builder().cost((int) (System.currentTimeMillis() - startTime))
|
||||
.interfaceName(processor.getClass().getSimpleName())
|
||||
.type(CostType.PROCESSOR.getType()).build());
|
||||
log.info("{} result:{}", processor.getClass().getSimpleName(), JsonUtil.toString(queryCtx));
|
||||
});
|
||||
|
||||
if (Objects.nonNull(parseResult.getQueryId()) && timeCostDOList.size() > 0) {
|
||||
saveTimeCostInfo(timeCostDOList, queryReq.getQueryText(), parseResult.getQueryId(),
|
||||
queryReq.getUser().getName(), queryReq.getChatId().longValue());
|
||||
}
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
private QueryContext buildQueryContext(QueryReq queryReq) {
|
||||
Integer agentId = queryReq.getAgentId();
|
||||
Agent agent = agentService.getAgent(agentId);
|
||||
|
||||
SemanticSchema semanticSchema = schemaService.getSemanticSchema();
|
||||
Map<Long, ChatConfigRichResp> modelIdToChatRichConfig = configService.getModelIdToChatRichConfig();
|
||||
|
||||
Map<String, Plugin> nameToPlugin = pluginService.getNameToPlugin();
|
||||
QueryContext queryCtx = QueryContext.builder()
|
||||
.request(queryReq)
|
||||
.semanticSchema(semanticSchema)
|
||||
.candidateQueries(new ArrayList<>())
|
||||
.mapInfo(new SchemaMapInfo())
|
||||
.agent(agent)
|
||||
.modelIdToChatRichConfig(modelIdToChatRichConfig)
|
||||
.nameToPlugin(nameToPlugin)
|
||||
.build();
|
||||
return queryCtx;
|
||||
}
|
||||
|
||||
@Override
|
||||
@TimeCost
|
||||
public QueryResult performExecution(ExecuteQueryReq queryReq) throws Exception {
|
||||
ChatParseDO chatParseDO = chatService.getParseInfo(queryReq.getQueryId(), queryReq.getParseId());
|
||||
ChatQueryDO chatQueryDO = chatService.getLastQuery(queryReq.getChatId());
|
||||
List<StatisticsDO> timeCostDOList = new ArrayList<>();
|
||||
SemanticParseInfo parseInfo = JsonUtil.toObject(chatParseDO.getParseInfo(), SemanticParseInfo.class);
|
||||
SemanticQuery semanticQuery = QueryManager.createQuery(parseInfo.getQueryMode());
|
||||
if (semanticQuery == null) {
|
||||
return null;
|
||||
}
|
||||
semanticQuery.setParseInfo(parseInfo);
|
||||
|
||||
// in order to support multi-turn conversation, chat context is needed
|
||||
ChatContext chatCtx = chatService.getOrCreateContext(queryReq.getChatId());
|
||||
chatCtx.setAgentId(queryReq.getAgentId());
|
||||
Long startTime = System.currentTimeMillis();
|
||||
QueryResult queryResult = semanticQuery.execute(queryReq.getUser());
|
||||
|
||||
if (queryResult != null) {
|
||||
timeCostDOList.add(StatisticsDO.builder().cost((int) (System.currentTimeMillis() - startTime))
|
||||
.interfaceName(semanticQuery.getClass().getSimpleName()).type(CostType.QUERY.getType()).build());
|
||||
queryResult.setQueryTimeCost(timeCostDOList.get(0).getCost().longValue());
|
||||
saveTimeCostInfo(timeCostDOList, queryReq.getQueryText(), queryReq.getQueryId(),
|
||||
queryReq.getUser().getName(), queryReq.getChatId().longValue());
|
||||
queryResult.setChatContext(parseInfo);
|
||||
// update chat context after a successful semantic query
|
||||
if (QueryState.SUCCESS.equals(queryResult.getQueryState())) {
|
||||
chatCtx.setParseInfo(parseInfo);
|
||||
chatService.updateContext(chatCtx);
|
||||
saveSolvedQuery(queryReq, parseInfo, chatQueryDO, queryResult);
|
||||
}
|
||||
chatCtx.setQueryText(queryReq.getQueryText());
|
||||
chatCtx.setUser(queryReq.getUser().getName());
|
||||
for (ExecuteResultProcessor executeResultProcessor : executeProcessors) {
|
||||
executeResultProcessor.process(queryResult, parseInfo, queryReq);
|
||||
}
|
||||
chatService.updateQuery(queryReq.getQueryId(), queryReq.getParseId(), queryResult, chatCtx);
|
||||
} else {
|
||||
chatService.deleteChatQuery(queryReq.getQueryId());
|
||||
}
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* save time cost data
|
||||
*
|
||||
* @param timeCostDOList
|
||||
* @param queryText
|
||||
* @param queryId
|
||||
* @param userName
|
||||
* @param chatId
|
||||
*/
|
||||
private void saveTimeCostInfo(List<StatisticsDO> timeCostDOList,
|
||||
String queryText, Long queryId,
|
||||
String userName, Long chatId) {
|
||||
List<StatisticsDO> list = timeCostDOList.stream()
|
||||
.filter(o -> o.getCost() > timeThreshold).collect(Collectors.toList());
|
||||
list.forEach(o -> {
|
||||
o.setQueryText(queryText);
|
||||
o.setQuestionId(queryId);
|
||||
o.setUserName(userName);
|
||||
o.setChatId(chatId);
|
||||
o.setCreateTime(new java.util.Date());
|
||||
});
|
||||
if (list.size() > 0) {
|
||||
log.info("filterStatistics size:{},data:{}", list.size(), JsonUtil.toString(list));
|
||||
statisticsService.batchSaveStatistics(list);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSolvedQuery(ExecuteQueryReq queryReq, SemanticParseInfo parseInfo,
|
||||
ChatQueryDO chatQueryDO, QueryResult queryResult) {
|
||||
if (queryResult.getResponse() == null && CollectionUtils.isEmpty(queryResult.getQueryResults())) {
|
||||
return;
|
||||
}
|
||||
similarQueryManager.saveSimilarQuery(SimilarQueryReq.builder().parseId(queryReq.getParseId())
|
||||
.queryId(queryReq.getQueryId())
|
||||
.agentId(chatQueryDO.getAgentId())
|
||||
.modelId(parseInfo.getModelClusterKey())
|
||||
.queryText(queryReq.getQueryText()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SemanticParseInfo queryContext(QueryReq queryCtx) {
|
||||
ChatContext context = chatService.getOrCreateContext(queryCtx.getChatId());
|
||||
return context.getParseInfo();
|
||||
}
|
||||
|
||||
//mainly used for executing after revising filters,for example:"fans_cnt>=100000"->"fans_cnt>500000",
|
||||
//"style='流行'"->"style in ['流行','爱国']"
|
||||
@Override
|
||||
@TimeCost
|
||||
public QueryResult executeDirectQuery(QueryDataReq queryData, User user) throws SqlParseException {
|
||||
ChatParseDO chatParseDO = chatService.getParseInfo(queryData.getQueryId(),
|
||||
queryData.getParseId());
|
||||
SemanticParseInfo parseInfo = getSemanticParseInfo(queryData, chatParseDO);
|
||||
SemanticSchema semanticSchema = schemaService.getSemanticSchema();
|
||||
|
||||
SemanticQuery semanticQuery = QueryManager.createQuery(parseInfo.getQueryMode());
|
||||
semanticQuery.setParseInfo(parseInfo);
|
||||
List<String> fields = new ArrayList<>();
|
||||
if (Objects.nonNull(parseInfo.getSqlInfo())
|
||||
&& StringUtils.isNotBlank(parseInfo.getSqlInfo().getCorrectS2SQL())) {
|
||||
String correctorSql = parseInfo.getSqlInfo().getCorrectS2SQL();
|
||||
fields = SqlParserSelectHelper.getAllFields(correctorSql);
|
||||
}
|
||||
if (LLMSqlQuery.QUERY_MODE.equalsIgnoreCase(parseInfo.getQueryMode())
|
||||
&& checkMetricReplace(fields, queryData.getMetrics())) {
|
||||
//replace metrics
|
||||
log.info("llm begin replace metrics!");
|
||||
SchemaElement metricToReplace = queryData.getMetrics().iterator().next();
|
||||
replaceMetrics(parseInfo, metricToReplace);
|
||||
} else if (LLMSqlQuery.QUERY_MODE.equalsIgnoreCase(parseInfo.getQueryMode())) {
|
||||
log.info("llm begin revise filters!");
|
||||
String correctorSql = reviseCorrectS2SQL(queryData, parseInfo);
|
||||
parseInfo.getSqlInfo().setCorrectS2SQL(correctorSql);
|
||||
semanticQuery.setParseInfo(parseInfo);
|
||||
String explainSql = semanticQuery.explain(user);
|
||||
if (StringUtils.isNotBlank(explainSql)) {
|
||||
parseInfo.getSqlInfo().setQuerySQL(explainSql);
|
||||
}
|
||||
} else {
|
||||
log.info("rule begin replace metrics and revise filters!");
|
||||
//remove unvalid filters
|
||||
validFilter(semanticQuery.getParseInfo().getDimensionFilters());
|
||||
validFilter(semanticQuery.getParseInfo().getMetricFilters());
|
||||
//init s2sql
|
||||
semanticQuery.initS2Sql(semanticSchema, user);
|
||||
QueryReq queryReq = new QueryReq();
|
||||
queryReq.setQueryFilters(new QueryFilters());
|
||||
queryReq.setUser(user);
|
||||
}
|
||||
QueryResult queryResult = semanticQuery.execute(user);
|
||||
queryResult.setChatContext(semanticQuery.getParseInfo());
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
EntityInfo entityInfo = semanticService.getEntityInfo(parseInfo, user);
|
||||
queryResult.setEntityInfo(entityInfo);
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
private boolean checkMetricReplace(List<String> oriFields, Set<SchemaElement> metrics) {
|
||||
if (CollectionUtils.isEmpty(oriFields)) {
|
||||
return false;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(metrics)) {
|
||||
return false;
|
||||
}
|
||||
List<String> metricNames = metrics.stream().map(SchemaElement::getName).collect(Collectors.toList());
|
||||
return !oriFields.containsAll(metricNames);
|
||||
}
|
||||
|
||||
public String reviseCorrectS2SQL(QueryDataReq queryData, SemanticParseInfo parseInfo) {
|
||||
Map<String, Map<String, String>> filedNameToValueMap = new HashMap<>();
|
||||
Map<String, Map<String, String>> havingFiledNameToValueMap = new HashMap<>();
|
||||
|
||||
String correctorSql = parseInfo.getSqlInfo().getCorrectS2SQL();
|
||||
log.info("correctorSql before replacing:{}", correctorSql);
|
||||
// get where filter and having filter
|
||||
List<FieldExpression> whereExpressionList = SqlParserSelectHelper.getWhereExpressions(correctorSql);
|
||||
List<FieldExpression> havingExpressionList = SqlParserSelectHelper.getHavingExpressions(correctorSql);
|
||||
List<Expression> addWhereConditions = new ArrayList<>();
|
||||
List<Expression> addHavingConditions = new ArrayList<>();
|
||||
Set<String> removeWhereFieldNames = new HashSet<>();
|
||||
Set<String> removeHavingFieldNames = new HashSet<>();
|
||||
// replace where filter
|
||||
updateFilters(whereExpressionList, queryData.getDimensionFilters(),
|
||||
parseInfo.getDimensionFilters(), addWhereConditions, removeWhereFieldNames);
|
||||
updateDateInfo(queryData, parseInfo, filedNameToValueMap,
|
||||
whereExpressionList, addWhereConditions, removeWhereFieldNames);
|
||||
correctorSql = SqlParserReplaceHelper.replaceValue(correctorSql, filedNameToValueMap);
|
||||
correctorSql = SqlParserRemoveHelper.removeWhereCondition(correctorSql, removeWhereFieldNames);
|
||||
// replace having filter
|
||||
updateFilters(havingExpressionList, queryData.getDimensionFilters(),
|
||||
parseInfo.getDimensionFilters(), addHavingConditions, removeHavingFieldNames);
|
||||
correctorSql = SqlParserReplaceHelper.replaceHavingValue(correctorSql, havingFiledNameToValueMap);
|
||||
correctorSql = SqlParserRemoveHelper.removeHavingCondition(correctorSql, removeHavingFieldNames);
|
||||
|
||||
correctorSql = SqlParserAddHelper.addWhere(correctorSql, addWhereConditions);
|
||||
correctorSql = SqlParserAddHelper.addHaving(correctorSql, addHavingConditions);
|
||||
log.info("correctorSql after replacing:{}", correctorSql);
|
||||
return correctorSql;
|
||||
}
|
||||
|
||||
private void replaceMetrics(SemanticParseInfo parseInfo, SchemaElement metric) {
|
||||
List<String> oriMetrics = parseInfo.getMetrics().stream()
|
||||
.map(SchemaElement::getName).collect(Collectors.toList());
|
||||
String correctorSql = parseInfo.getSqlInfo().getCorrectS2SQL();
|
||||
log.info("before replaceMetrics:{}", correctorSql);
|
||||
log.info("filteredMetrics:{},metrics:{}", oriMetrics, metric);
|
||||
Map<String, Pair<String, String>> fieldMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(oriMetrics) && !oriMetrics.contains(metric.getName())) {
|
||||
fieldMap.put(oriMetrics.get(0), Pair.of(metric.getName(), metric.getDefaultAgg()));
|
||||
correctorSql = SqlParserReplaceHelper.replaceAggFields(correctorSql, fieldMap);
|
||||
}
|
||||
log.info("after replaceMetrics:{}", correctorSql);
|
||||
parseInfo.getSqlInfo().setCorrectS2SQL(correctorSql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInfo getEntityInfo(Long queryId, Integer parseId, User user) {
|
||||
ChatParseDO chatParseDO = chatService.getParseInfo(queryId, parseId);
|
||||
SemanticParseInfo parseInfo = JsonUtil.toObject(chatParseDO.getParseInfo(), SemanticParseInfo.class);
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
return semanticService.getEntityInfo(parseInfo, user);
|
||||
}
|
||||
|
||||
private void updateDateInfo(QueryDataReq queryData, SemanticParseInfo parseInfo,
|
||||
Map<String, Map<String, String>> filedNameToValueMap,
|
||||
List<FieldExpression> fieldExpressionList,
|
||||
List<Expression> addConditions,
|
||||
Set<String> removeFieldNames) {
|
||||
if (Objects.isNull(queryData.getDateInfo())) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> map = new HashMap<>();
|
||||
String dateField = TimeDimensionEnum.DAY.getChName();
|
||||
if (queryData.getDateInfo().getUnit() > 1) {
|
||||
queryData.getDateInfo().setStartDate(DateUtils.getBeforeDate(queryData.getDateInfo().getUnit() + 1));
|
||||
queryData.getDateInfo().setEndDate(DateUtils.getBeforeDate(1));
|
||||
}
|
||||
// startDate equals to endDate
|
||||
if (queryData.getDateInfo().getStartDate().equals(queryData.getDateInfo().getEndDate())) {
|
||||
for (FieldExpression fieldExpression : fieldExpressionList) {
|
||||
if (TimeDimensionEnum.DAY.getChName().equals(fieldExpression.getFieldName())) {
|
||||
//sql where condition exists 'equals' operator about date,just replace
|
||||
if (fieldExpression.getOperator().equals(FilterOperatorEnum.EQUALS)) {
|
||||
dateField = fieldExpression.getFieldName();
|
||||
map.put(fieldExpression.getFieldValue().toString(),
|
||||
queryData.getDateInfo().getStartDate());
|
||||
filedNameToValueMap.put(dateField, map);
|
||||
} else {
|
||||
// first remove,then add
|
||||
removeFieldNames.add(TimeDimensionEnum.DAY.getChName());
|
||||
EqualsTo equalsTo = new EqualsTo();
|
||||
Column column = new Column(TimeDimensionEnum.DAY.getChName());
|
||||
StringValue stringValue = new StringValue(queryData.getDateInfo().getStartDate());
|
||||
equalsTo.setLeftExpression(column);
|
||||
equalsTo.setRightExpression(stringValue);
|
||||
addConditions.add(equalsTo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (FieldExpression fieldExpression : fieldExpressionList) {
|
||||
if (TimeDimensionEnum.DAY.getChName().equals(fieldExpression.getFieldName())) {
|
||||
dateField = fieldExpression.getFieldName();
|
||||
//just replace
|
||||
if (FilterOperatorEnum.GREATER_THAN_EQUALS.getValue().equals(fieldExpression.getOperator())
|
||||
|| FilterOperatorEnum.GREATER_THAN.getValue().equals(fieldExpression.getOperator())) {
|
||||
map.put(fieldExpression.getFieldValue().toString(),
|
||||
queryData.getDateInfo().getStartDate());
|
||||
}
|
||||
if (FilterOperatorEnum.MINOR_THAN_EQUALS.getValue().equals(fieldExpression.getOperator())
|
||||
|| FilterOperatorEnum.MINOR_THAN.getValue().equals(fieldExpression.getOperator())) {
|
||||
map.put(fieldExpression.getFieldValue().toString(),
|
||||
queryData.getDateInfo().getEndDate());
|
||||
}
|
||||
filedNameToValueMap.put(dateField, map);
|
||||
// first remove,then add
|
||||
if (FilterOperatorEnum.EQUALS.getValue().equals(fieldExpression.getOperator())) {
|
||||
removeFieldNames.add(TimeDimensionEnum.DAY.getChName());
|
||||
GreaterThanEquals greaterThanEquals = new GreaterThanEquals();
|
||||
addTimeFilters(queryData.getDateInfo().getStartDate(), greaterThanEquals, addConditions);
|
||||
MinorThanEquals minorThanEquals = new MinorThanEquals();
|
||||
addTimeFilters(queryData.getDateInfo().getEndDate(), minorThanEquals, addConditions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parseInfo.setDateInfo(queryData.getDateInfo());
|
||||
}
|
||||
|
||||
private <T extends ComparisonOperator> void addTimeFilters(String date,
|
||||
T comparisonExpression,
|
||||
List<Expression> addConditions) {
|
||||
Column column = new Column(TimeDimensionEnum.DAY.getChName());
|
||||
StringValue stringValue = new StringValue(date);
|
||||
comparisonExpression.setLeftExpression(column);
|
||||
comparisonExpression.setRightExpression(stringValue);
|
||||
addConditions.add(comparisonExpression);
|
||||
}
|
||||
|
||||
private void updateFilters(List<FieldExpression> fieldExpressionList,
|
||||
Set<QueryFilter> metricFilters,
|
||||
Set<QueryFilter> contextMetricFilters,
|
||||
List<Expression> addConditions,
|
||||
Set<String> removeFieldNames) {
|
||||
if (CollectionUtils.isEmpty(metricFilters)) {
|
||||
return;
|
||||
}
|
||||
for (QueryFilter dslQueryFilter : metricFilters) {
|
||||
for (FieldExpression fieldExpression : fieldExpressionList) {
|
||||
if (fieldExpression.getFieldName() != null
|
||||
&& fieldExpression.getFieldName().contains(dslQueryFilter.getName())) {
|
||||
removeFieldNames.add(dslQueryFilter.getName());
|
||||
if (dslQueryFilter.getOperator().equals(FilterOperatorEnum.EQUALS)) {
|
||||
EqualsTo equalsTo = new EqualsTo();
|
||||
addWhereFilters(dslQueryFilter, equalsTo, contextMetricFilters, addConditions);
|
||||
} else if (dslQueryFilter.getOperator().equals(FilterOperatorEnum.GREATER_THAN_EQUALS)) {
|
||||
GreaterThanEquals greaterThanEquals = new GreaterThanEquals();
|
||||
addWhereFilters(dslQueryFilter, greaterThanEquals, contextMetricFilters, addConditions);
|
||||
} else if (dslQueryFilter.getOperator().equals(FilterOperatorEnum.GREATER_THAN)) {
|
||||
GreaterThan greaterThan = new GreaterThan();
|
||||
addWhereFilters(dslQueryFilter, greaterThan, contextMetricFilters, addConditions);
|
||||
} else if (dslQueryFilter.getOperator().equals(FilterOperatorEnum.MINOR_THAN_EQUALS)) {
|
||||
MinorThanEquals minorThanEquals = new MinorThanEquals();
|
||||
addWhereFilters(dslQueryFilter, minorThanEquals, contextMetricFilters, addConditions);
|
||||
} else if (dslQueryFilter.getOperator().equals(FilterOperatorEnum.MINOR_THAN)) {
|
||||
MinorThan minorThan = new MinorThan();
|
||||
addWhereFilters(dslQueryFilter, minorThan, contextMetricFilters, addConditions);
|
||||
} else if (dslQueryFilter.getOperator().equals(FilterOperatorEnum.IN)) {
|
||||
InExpression inExpression = new InExpression();
|
||||
addWhereInFilters(dslQueryFilter, inExpression, contextMetricFilters, addConditions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add in condition to sql where condition
|
||||
private void addWhereInFilters(QueryFilter dslQueryFilter,
|
||||
InExpression inExpression,
|
||||
Set<QueryFilter> contextMetricFilters,
|
||||
List<Expression> addConditions) {
|
||||
Column column = new Column(dslQueryFilter.getName());
|
||||
ExpressionList expressionList = new ExpressionList();
|
||||
List<Expression> expressions = new ArrayList<>();
|
||||
List<String> valueList = JsonUtil.toList(
|
||||
JsonUtil.toString(dslQueryFilter.getValue()), String.class);
|
||||
if (CollectionUtils.isEmpty(valueList)) {
|
||||
return;
|
||||
}
|
||||
valueList.stream().forEach(o -> {
|
||||
StringValue stringValue = new StringValue(o);
|
||||
expressions.add(stringValue);
|
||||
});
|
||||
expressionList.setExpressions(expressions);
|
||||
inExpression.setLeftExpression(column);
|
||||
inExpression.setRightItemsList(expressionList);
|
||||
addConditions.add(inExpression);
|
||||
contextMetricFilters.stream().forEach(o -> {
|
||||
if (o.getName().equals(dslQueryFilter.getName())) {
|
||||
o.setValue(dslQueryFilter.getValue());
|
||||
o.setOperator(dslQueryFilter.getOperator());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// add where filter
|
||||
private <T extends ComparisonOperator> void addWhereFilters(QueryFilter dslQueryFilter,
|
||||
T comparisonExpression,
|
||||
Set<QueryFilter> contextMetricFilters,
|
||||
List<Expression> addConditions) {
|
||||
String columnName = dslQueryFilter.getName();
|
||||
if (StringUtils.isNotBlank(dslQueryFilter.getFunction())) {
|
||||
columnName = dslQueryFilter.getFunction() + "(" + dslQueryFilter.getName() + ")";
|
||||
}
|
||||
if (Objects.isNull(dslQueryFilter.getValue())) {
|
||||
return;
|
||||
}
|
||||
Column column = new Column(columnName);
|
||||
comparisonExpression.setLeftExpression(column);
|
||||
if (StringUtils.isNumeric(dslQueryFilter.getValue().toString())) {
|
||||
LongValue longValue = new LongValue(Long.parseLong(dslQueryFilter.getValue().toString()));
|
||||
comparisonExpression.setRightExpression(longValue);
|
||||
} else {
|
||||
StringValue stringValue = new StringValue(dslQueryFilter.getValue().toString());
|
||||
comparisonExpression.setRightExpression(stringValue);
|
||||
}
|
||||
addConditions.add(comparisonExpression);
|
||||
contextMetricFilters.stream().forEach(o -> {
|
||||
if (o.getName().equals(dslQueryFilter.getName())) {
|
||||
o.setValue(dslQueryFilter.getValue());
|
||||
o.setOperator(dslQueryFilter.getOperator());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private SemanticParseInfo getSemanticParseInfo(QueryDataReq queryData, ChatParseDO chatParseDO) {
|
||||
SemanticParseInfo parseInfo = JsonUtil.toObject(chatParseDO.getParseInfo(), SemanticParseInfo.class);
|
||||
if (LLMSqlQuery.QUERY_MODE.equals(parseInfo.getQueryMode())) {
|
||||
return parseInfo;
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(queryData.getDimensions())) {
|
||||
parseInfo.setDimensions(queryData.getDimensions());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(queryData.getMetrics())) {
|
||||
parseInfo.setMetrics(queryData.getMetrics());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(queryData.getDimensionFilters())) {
|
||||
parseInfo.setDimensionFilters(queryData.getDimensionFilters());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(queryData.getMetricFilters())) {
|
||||
parseInfo.setMetricFilters(queryData.getMetricFilters());
|
||||
}
|
||||
if (Objects.nonNull(queryData.getDateInfo())) {
|
||||
parseInfo.setDateInfo(queryData.getDateInfo());
|
||||
}
|
||||
return parseInfo;
|
||||
}
|
||||
|
||||
private void validFilter(Set<QueryFilter> filters) {
|
||||
for (QueryFilter queryFilter : filters) {
|
||||
if (Objects.isNull(queryFilter.getValue())) {
|
||||
filters.remove(queryFilter);
|
||||
}
|
||||
if (queryFilter.getOperator().equals(FilterOperatorEnum.IN) && CollectionUtils.isEmpty(
|
||||
JsonUtil.toList(JsonUtil.toString(queryFilter.getValue()), String.class))) {
|
||||
filters.remove(queryFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object queryDimensionValue(DimensionValueReq dimensionValueReq, User user) throws Exception {
|
||||
QueryResultWithSchemaResp queryResultWithSchemaResp = new QueryResultWithSchemaResp();
|
||||
SemanticService semanticService = ContextUtils.getBean(SemanticService.class);
|
||||
SemanticSchema semanticSchema = semanticService.getSemanticSchema();
|
||||
SchemaElement schemaElement = semanticSchema.getDimensions(dimensionValueReq.getElementID());
|
||||
Set<Long> detectModelIds = new HashSet<>();
|
||||
detectModelIds.add(schemaElement.getModel());
|
||||
dimensionValueReq.setModelId(schemaElement.getModel());
|
||||
List<String> dimensionValues = getDimensionValues(dimensionValueReq, detectModelIds);
|
||||
// if the search results is null,search dimensionValue from database
|
||||
if (CollectionUtils.isEmpty(dimensionValues)) {
|
||||
queryResultWithSchemaResp = queryDatabase(dimensionValueReq, user);
|
||||
return queryResultWithSchemaResp;
|
||||
}
|
||||
List<QueryColumn> columns = new ArrayList<>();
|
||||
QueryColumn queryColumn = new QueryColumn();
|
||||
queryColumn.setNameEn(dimensionValueReq.getBizName());
|
||||
queryColumn.setShowType("CATEGORY");
|
||||
queryColumn.setAuthorized(true);
|
||||
queryColumn.setType("CHAR");
|
||||
columns.add(queryColumn);
|
||||
List<Map<String, Object>> resultList = new ArrayList<>();
|
||||
dimensionValues.stream().forEach(o -> {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(dimensionValueReq.getBizName(), o);
|
||||
resultList.add(map);
|
||||
});
|
||||
queryResultWithSchemaResp.setColumns(columns);
|
||||
queryResultWithSchemaResp.setResultList(resultList);
|
||||
return queryResultWithSchemaResp;
|
||||
}
|
||||
|
||||
private List<String> getDimensionValues(DimensionValueReq dimensionValueReq, Set<Long> detectModelIds) {
|
||||
//if value is null ,then search from NATURE_TO_VALUES
|
||||
if (StringUtils.isBlank(dimensionValueReq.getValue())) {
|
||||
return SearchService.getDimensionValue(dimensionValueReq);
|
||||
}
|
||||
//search from prefixSearch
|
||||
List<HanlpMapResult> hanlpMapResultList = SearchService.prefixSearch(dimensionValueReq.getValue(),
|
||||
2000, dimensionValueReq.getAgentId(), detectModelIds);
|
||||
HanlpHelper.transLetterOriginal(hanlpMapResultList);
|
||||
return hanlpMapResultList.stream()
|
||||
.filter(o -> {
|
||||
for (String nature : o.getNatures()) {
|
||||
Long elementID = NatureHelper.getElementID(nature);
|
||||
if (dimensionValueReq.getElementID().equals(elementID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.map(mapResult -> mapResult.getName())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private QueryResultWithSchemaResp queryDatabase(DimensionValueReq dimensionValueReq, User user) {
|
||||
QueryStructReq queryStructReq = new QueryStructReq();
|
||||
|
||||
DateConf dateConf = new DateConf();
|
||||
dateConf.setDateMode(DateConf.DateMode.RECENT);
|
||||
dateConf.setUnit(1);
|
||||
dateConf.setPeriod("DAY");
|
||||
queryStructReq.setDateInfo(dateConf);
|
||||
queryStructReq.setLimit(20L);
|
||||
queryStructReq.setModelId(dimensionValueReq.getModelId());
|
||||
queryStructReq.setQueryType(QueryType.ID);
|
||||
List<String> groups = new ArrayList<>();
|
||||
groups.add(dimensionValueReq.getBizName());
|
||||
queryStructReq.setGroups(groups);
|
||||
SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
return semanticInterpreter.queryByStruct(queryStructReq, user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.RelatedSchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.RecommendQuestionResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.RecommendResp;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import com.tencent.supersonic.chat.server.service.RecommendService;
|
||||
import com.tencent.supersonic.chat.server.service.SemanticService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/***
|
||||
* Recommend Service impl
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class RecommendServiceImpl implements RecommendService {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private SemanticService semanticService;
|
||||
|
||||
@Override
|
||||
public RecommendResp recommend(RecommendReq recommendReq, Long limit) {
|
||||
if (Objects.isNull(limit) || limit <= 0) {
|
||||
limit = Long.MAX_VALUE;
|
||||
}
|
||||
log.debug("limit:{}", limit);
|
||||
Long modelId = recommendReq.getModelId();
|
||||
if (Objects.isNull(modelId)) {
|
||||
return new RecommendResp();
|
||||
}
|
||||
ModelSchema modelSchema = semanticService.getModelSchema(modelId);
|
||||
if (Objects.isNull(modelSchema)) {
|
||||
return new RecommendResp();
|
||||
}
|
||||
List<Long> drillDownDimensions = Lists.newArrayList();
|
||||
Set<SchemaElement> metricElements = modelSchema.getMetrics();
|
||||
if (recommendReq.getMetricId() != null && !CollectionUtils.isEmpty(metricElements)) {
|
||||
Optional<SchemaElement> metric = metricElements.stream().filter(schemaElement ->
|
||||
recommendReq.getMetricId().equals(schemaElement.getId())
|
||||
&& !CollectionUtils.isEmpty(schemaElement.getRelatedSchemaElements()))
|
||||
.findFirst();
|
||||
if (metric.isPresent()) {
|
||||
drillDownDimensions = metric.get().getRelatedSchemaElements().stream()
|
||||
.map(RelatedSchemaElement::getDimensionId).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
final List<Long> drillDownDimensionsFinal = drillDownDimensions;
|
||||
List<SchemaElement> dimensions = modelSchema.getDimensions().stream()
|
||||
.filter(dim -> {
|
||||
if (Objects.isNull(dim)) {
|
||||
return false;
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(drillDownDimensionsFinal)) {
|
||||
return drillDownDimensionsFinal.contains(dim.getId());
|
||||
} else {
|
||||
return Objects.nonNull(dim.getUseCnt());
|
||||
}
|
||||
})
|
||||
.sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed())
|
||||
.limit(limit)
|
||||
.map(dimSchemaDesc -> {
|
||||
SchemaElement item = new SchemaElement();
|
||||
item.setModel(modelId);
|
||||
item.setName(dimSchemaDesc.getName());
|
||||
item.setBizName(dimSchemaDesc.getBizName());
|
||||
item.setId(dimSchemaDesc.getId());
|
||||
item.setAlias(dimSchemaDesc.getAlias());
|
||||
return item;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<SchemaElement> metrics = modelSchema.getMetrics().stream()
|
||||
.filter(metric -> Objects.nonNull(metric) && Objects.nonNull(metric.getUseCnt()))
|
||||
.sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed())
|
||||
.limit(limit)
|
||||
.map(metricSchemaDesc -> {
|
||||
SchemaElement item = new SchemaElement();
|
||||
item.setModel(modelId);
|
||||
item.setName(metricSchemaDesc.getName());
|
||||
item.setBizName(metricSchemaDesc.getBizName());
|
||||
item.setId(metricSchemaDesc.getId());
|
||||
item.setAlias(metricSchemaDesc.getAlias());
|
||||
return item;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
RecommendResp response = new RecommendResp();
|
||||
response.setDimensions(dimensions);
|
||||
response.setMetrics(metrics);
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecommendResp recommendMetricMode(RecommendReq recommendReq, Long limit) {
|
||||
return recommend(recommendReq, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RecommendQuestionResp> recommendQuestion(Long modelId) {
|
||||
List<RecommendQuestionResp> recommendQuestions = new ArrayList<>();
|
||||
ChatConfigFilter chatConfigFilter = new ChatConfigFilter();
|
||||
chatConfigFilter.setModelId(modelId);
|
||||
List<ChatConfigResp> chatConfigRespList = configService.search(chatConfigFilter, null);
|
||||
if (!CollectionUtils.isEmpty(chatConfigRespList)) {
|
||||
chatConfigRespList.stream().forEach(chatConfigResp -> {
|
||||
if (Objects.nonNull(chatConfigResp)
|
||||
&& !CollectionUtils.isEmpty(chatConfigResp.getRecommendedQuestions())) {
|
||||
recommendQuestions.add(
|
||||
new RecommendQuestionResp(chatConfigResp.getModelId(),
|
||||
chatConfigResp.getRecommendedQuestions()));
|
||||
}
|
||||
});
|
||||
return recommendQuestions;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private List<SchemaElement> filterBlackItem(List<SchemaElement> itemList, List<Long> blackDimIdList) {
|
||||
if (CollectionUtils.isEmpty(blackDimIdList) || CollectionUtils.isEmpty(itemList)) {
|
||||
return itemList;
|
||||
}
|
||||
|
||||
return itemList.stream().filter(dim -> !blackDimIdList.contains(dim.getId())).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SchemaService {
|
||||
|
||||
|
||||
public static final String ALL_CACHE = "all";
|
||||
private static final Integer META_CACHE_TIME = 30;
|
||||
private SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
|
||||
private LoadingCache<String, SemanticSchema> cache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(META_CACHE_TIME, TimeUnit.SECONDS)
|
||||
.build(
|
||||
new CacheLoader<String, SemanticSchema>() {
|
||||
@Override
|
||||
public SemanticSchema load(String key) {
|
||||
log.info("load getDomainSchemaInfo cache [{}]", key);
|
||||
return new SemanticSchema(semanticInterpreter.getModelSchema());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
public ModelSchema getModelSchema(Long id) {
|
||||
return semanticInterpreter.getModelSchema(id, true);
|
||||
}
|
||||
|
||||
public SemanticSchema getSemanticSchema() {
|
||||
return cache.getUnchecked(ALL_CACHE);
|
||||
}
|
||||
|
||||
public LoadingCache<String, SemanticSchema> getCache() {
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.hankcs.hanlp.seg.common.Term;
|
||||
import com.tencent.supersonic.chat.core.pojo.QueryContext;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElementType;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ItemNameVisibilityInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilter;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryFilters;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.QueryReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.SearchResult;
|
||||
import com.tencent.supersonic.chat.core.agent.Agent;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictWord;
|
||||
import com.tencent.supersonic.chat.core.knowledge.HanlpMapResult;
|
||||
import com.tencent.supersonic.chat.core.knowledge.ModelInfoStat;
|
||||
import com.tencent.supersonic.chat.core.mapper.MapperHelper;
|
||||
import com.tencent.supersonic.chat.core.mapper.MatchText;
|
||||
import com.tencent.supersonic.chat.core.mapper.ModelWithSemanticType;
|
||||
import com.tencent.supersonic.chat.core.mapper.SearchMatchStrategy;
|
||||
import com.tencent.supersonic.chat.core.utils.HanlpHelper;
|
||||
import com.tencent.supersonic.chat.core.utils.NatureHelper;
|
||||
import com.tencent.supersonic.chat.server.service.AgentService;
|
||||
import com.tencent.supersonic.chat.server.service.ChatService;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import com.tencent.supersonic.chat.server.service.SearchService;
|
||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* search service impl
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SearchServiceImpl implements SearchService {
|
||||
|
||||
private static final int RESULT_SIZE = 10;
|
||||
@Autowired
|
||||
private SchemaService schemaService;
|
||||
@Autowired
|
||||
private ChatService chatService;
|
||||
@Autowired
|
||||
private SearchMatchStrategy searchMatchStrategy;
|
||||
@Autowired
|
||||
private AgentService agentService;
|
||||
@Autowired
|
||||
@Qualifier("searchCaffeineCache")
|
||||
private Cache<Long, Object> caffeineCache;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
public List<SearchResult> search(QueryReq queryReq) {
|
||||
// 1. check search enable
|
||||
Integer agentId = queryReq.getAgentId();
|
||||
if (agentId != null) {
|
||||
Agent agent = agentService.getAgent(agentId);
|
||||
if (!agent.enableSearch()) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
String queryText = queryReq.getQueryText();
|
||||
// 2.get meta info
|
||||
SemanticSchema semanticSchemaDb = schemaService.getSemanticSchema();
|
||||
List<SchemaElement> metricsDb = semanticSchemaDb.getMetrics();
|
||||
final Map<Long, String> modelToName = semanticSchemaDb.getModelIdToName();
|
||||
|
||||
// 3.detect by segment
|
||||
List<Term> originals = HanlpHelper.getTerms(queryText);
|
||||
log.info("hanlp parse result: {}", originals);
|
||||
MapperHelper mapperHelper = ContextUtils.getBean(MapperHelper.class);
|
||||
Set<Long> detectModelIds = mapperHelper.getModelIds(queryReq, agentService.getAgent(agentId));
|
||||
|
||||
QueryContext queryContext = new QueryContext();
|
||||
queryContext.setRequest(queryReq);
|
||||
Map<MatchText, List<HanlpMapResult>> regTextMap =
|
||||
searchMatchStrategy.match(queryContext, originals, detectModelIds);
|
||||
regTextMap.entrySet().stream().forEach(m -> HanlpHelper.transLetterOriginal(m.getValue()));
|
||||
|
||||
// 4.get the most matching data
|
||||
Optional<Entry<MatchText, List<HanlpMapResult>>> mostSimilarSearchResult = regTextMap.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> CollectionUtils.isNotEmpty(entry.getValue()))
|
||||
.reduce((entry1, entry2) ->
|
||||
entry1.getKey().getDetectSegment().length() >= entry2.getKey().getDetectSegment().length()
|
||||
? entry1 : entry2);
|
||||
|
||||
// 5.optimize the results after the query
|
||||
if (!mostSimilarSearchResult.isPresent()) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
Map.Entry<MatchText, List<HanlpMapResult>> searchTextEntry = mostSimilarSearchResult.get();
|
||||
log.info("searchTextEntry:{},queryReq:{}", searchTextEntry, queryReq);
|
||||
|
||||
Set<SearchResult> searchResults = new LinkedHashSet();
|
||||
ModelInfoStat modelStat = NatureHelper.getModelStat(originals);
|
||||
|
||||
List<Long> possibleModels = getPossibleModels(queryReq, originals, modelStat, queryReq.getModelId());
|
||||
|
||||
// 5.1 priority dimension metric
|
||||
boolean existMetricAndDimension = searchMetricAndDimension(new HashSet<>(possibleModels), modelToName,
|
||||
searchTextEntry, searchResults);
|
||||
|
||||
// 5.2 process based on dimension values
|
||||
MatchText matchText = searchTextEntry.getKey();
|
||||
Map<String, String> natureToNameMap = getNatureToNameMap(searchTextEntry, new HashSet<>(possibleModels));
|
||||
log.debug("possibleModels:{},natureToNameMap:{}", possibleModels, natureToNameMap);
|
||||
|
||||
for (Map.Entry<String, String> natureToNameEntry : natureToNameMap.entrySet()) {
|
||||
|
||||
Set<SearchResult> searchResultSet = searchDimensionValue(metricsDb, modelToName,
|
||||
modelStat.getMetricModelCount(), existMetricAndDimension,
|
||||
matchText, natureToNameMap, natureToNameEntry, queryReq.getQueryFilters());
|
||||
|
||||
searchResults.addAll(searchResultSet);
|
||||
}
|
||||
return searchResults.stream().limit(RESULT_SIZE).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Long> getPossibleModels(QueryReq queryCtx, List<Term> originals,
|
||||
ModelInfoStat modelStat, Long webModelId) {
|
||||
|
||||
if (Objects.nonNull(webModelId) && webModelId > 0) {
|
||||
List<Long> result = new ArrayList<>();
|
||||
result.add(webModelId);
|
||||
return result;
|
||||
}
|
||||
|
||||
List<Long> possibleModels = NatureHelper.selectPossibleModels(originals);
|
||||
|
||||
Set<Long> contextModel = chatService.getContextModel(queryCtx.getChatId());
|
||||
|
||||
log.debug("possibleModels:{},modelStat:{},contextModel:{}", possibleModels, modelStat, contextModel);
|
||||
|
||||
// If nothing is recognized or only metric are present, then add the contextModel.
|
||||
if (nothingOrOnlyMetric(modelStat)) {
|
||||
return contextModel.stream().filter(modelId -> modelId > 0).collect(Collectors.toList());
|
||||
}
|
||||
return possibleModels;
|
||||
}
|
||||
|
||||
private boolean nothingOrOnlyMetric(ModelInfoStat modelStat) {
|
||||
return modelStat.getMetricModelCount() >= 0 && modelStat.getDimensionModelCount() <= 0
|
||||
&& modelStat.getDimensionValueModelCount() <= 0 && modelStat.getModelCount() <= 0;
|
||||
}
|
||||
|
||||
private boolean effectiveModel(Long contextModel) {
|
||||
return Objects.nonNull(contextModel) && contextModel > 0;
|
||||
}
|
||||
|
||||
private Set<SearchResult> searchDimensionValue(List<SchemaElement> metricsDb,
|
||||
Map<Long, String> modelToName,
|
||||
long metricModelCount,
|
||||
boolean existMetricAndDimension,
|
||||
MatchText matchText,
|
||||
Map<String, String> natureToNameMap,
|
||||
Map.Entry<String, String> natureToNameEntry,
|
||||
QueryFilters queryFilters) {
|
||||
|
||||
Set<SearchResult> searchResults = new LinkedHashSet();
|
||||
String nature = natureToNameEntry.getKey();
|
||||
String wordName = natureToNameEntry.getValue();
|
||||
|
||||
Long modelId = NatureHelper.getModelId(nature);
|
||||
SchemaElementType schemaElementType = NatureHelper.convertToElementType(nature);
|
||||
|
||||
if (SchemaElementType.ENTITY.equals(schemaElementType)) {
|
||||
return searchResults;
|
||||
}
|
||||
// If there are no metric/dimension, complete the metric information
|
||||
SearchResult searchResult = SearchResult.builder()
|
||||
.modelId(modelId)
|
||||
.modelName(modelToName.get(modelId))
|
||||
.recommend(matchText.getRegText() + wordName)
|
||||
.schemaElementType(schemaElementType)
|
||||
.subRecommend(wordName)
|
||||
.build();
|
||||
ItemNameVisibilityInfo visibility = (ItemNameVisibilityInfo) caffeineCache.getIfPresent(modelId);
|
||||
if (visibility == null) {
|
||||
visibility = configService.getVisibilityByModelId(modelId);
|
||||
caffeineCache.put(modelId, visibility);
|
||||
}
|
||||
if (visibility.getBlackMetricNameList().contains(searchResult.getRecommend())
|
||||
|| visibility.getBlackDimNameList().contains(searchResult.getRecommend())) {
|
||||
return searchResults;
|
||||
}
|
||||
if (metricModelCount <= 0 && !existMetricAndDimension) {
|
||||
if (filterByQueryFilter(wordName, queryFilters)) {
|
||||
return searchResults;
|
||||
}
|
||||
searchResults.add(searchResult);
|
||||
int metricSize = getMetricSize(natureToNameMap);
|
||||
//invisibility to filter metrics
|
||||
List<String> blackMetricNameList = visibility.getBlackMetricNameList();
|
||||
List<String> metrics = filerMetricsByModel(metricsDb, modelId, metricSize * 3)
|
||||
.stream().filter(o -> !blackMetricNameList.contains(o))
|
||||
.limit(metricSize).collect(Collectors.toList());
|
||||
|
||||
for (String metric : metrics) {
|
||||
SearchResult result = SearchResult.builder()
|
||||
.modelId(modelId)
|
||||
.modelName(modelToName.get(modelId))
|
||||
.recommend(matchText.getRegText() + wordName + DictWordType.SPACE + metric)
|
||||
.subRecommend(wordName + DictWordType.SPACE + metric)
|
||||
.isComplete(false)
|
||||
.build();
|
||||
searchResults.add(result);
|
||||
}
|
||||
} else {
|
||||
searchResults.add(searchResult);
|
||||
}
|
||||
return searchResults;
|
||||
}
|
||||
|
||||
private int getMetricSize(Map<String, String> natureToNameMap) {
|
||||
int metricSize = RESULT_SIZE / (natureToNameMap.entrySet().size());
|
||||
if (metricSize <= 1) {
|
||||
metricSize = 1;
|
||||
}
|
||||
return metricSize;
|
||||
}
|
||||
|
||||
private boolean filterByQueryFilter(String wordName, QueryFilters queryFilters) {
|
||||
if (queryFilters == null || CollectionUtils.isEmpty(queryFilters.getFilters())) {
|
||||
return false;
|
||||
}
|
||||
List<QueryFilter> filters = queryFilters.getFilters();
|
||||
for (QueryFilter filter : filters) {
|
||||
if (wordName.equalsIgnoreCase(String.valueOf(filter.getValue()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected List<String> filerMetricsByModel(List<SchemaElement> metricsDb, Long model, int metricSize) {
|
||||
if (CollectionUtils.isEmpty(metricsDb)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return metricsDb.stream()
|
||||
.filter(mapDO -> Objects.nonNull(mapDO) && model.equals(mapDO.getModel()))
|
||||
.sorted(Comparator.comparing(SchemaElement::getUseCnt).reversed())
|
||||
.flatMap(entry -> {
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(entry.getName());
|
||||
return result.stream();
|
||||
})
|
||||
.limit(metricSize).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/***
|
||||
* convert nature to name
|
||||
* @param recommendTextListEntry
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> getNatureToNameMap(Map.Entry<MatchText, List<HanlpMapResult>> recommendTextListEntry,
|
||||
Set<Long> possibleModels) {
|
||||
List<HanlpMapResult> recommendValues = recommendTextListEntry.getValue();
|
||||
return recommendValues.stream()
|
||||
.flatMap(entry -> entry.getNatures().stream()
|
||||
.filter(nature -> {
|
||||
if (CollectionUtils.isEmpty(possibleModels)) {
|
||||
return true;
|
||||
}
|
||||
Long model = NatureHelper.getModelId(nature);
|
||||
return possibleModels.contains(model);
|
||||
})
|
||||
.map(nature -> {
|
||||
DictWord posDO = new DictWord();
|
||||
posDO.setWord(entry.getName());
|
||||
posDO.setNature(nature);
|
||||
return posDO;
|
||||
})).sorted(Comparator.comparingInt(a -> a.getWord().length()))
|
||||
.collect(Collectors.toMap(DictWord::getNature, DictWord::getWord, (value1, value2) -> value1,
|
||||
LinkedHashMap::new));
|
||||
}
|
||||
|
||||
private boolean searchMetricAndDimension(Set<Long> possibleModels, Map<Long, String> modelToName,
|
||||
Map.Entry<MatchText, List<HanlpMapResult>> searchTextEntry, Set<SearchResult> searchResults) {
|
||||
boolean existMetric = false;
|
||||
log.info("searchMetricAndDimension searchTextEntry:{}", searchTextEntry);
|
||||
MatchText matchText = searchTextEntry.getKey();
|
||||
List<HanlpMapResult> hanlpMapResults = searchTextEntry.getValue();
|
||||
|
||||
for (HanlpMapResult hanlpMapResult : hanlpMapResults) {
|
||||
|
||||
List<ModelWithSemanticType> dimensionMetricClassIds = hanlpMapResult.getNatures().stream()
|
||||
.map(nature -> new ModelWithSemanticType(NatureHelper.getModelId(nature),
|
||||
NatureHelper.convertToElementType(nature)))
|
||||
.filter(entry -> matchCondition(entry, possibleModels)).collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(dimensionMetricClassIds)) {
|
||||
continue;
|
||||
}
|
||||
for (ModelWithSemanticType modelWithSemanticType : dimensionMetricClassIds) {
|
||||
existMetric = true;
|
||||
Long modelId = modelWithSemanticType.getModel();
|
||||
SchemaElementType schemaElementType = modelWithSemanticType.getSchemaElementType();
|
||||
SearchResult searchResult = SearchResult.builder()
|
||||
.modelId(modelId)
|
||||
.modelName(modelToName.get(modelId))
|
||||
.recommend(matchText.getRegText() + hanlpMapResult.getName())
|
||||
.subRecommend(hanlpMapResult.getName())
|
||||
.schemaElementType(schemaElementType)
|
||||
.build();
|
||||
//visibility to filter metrics
|
||||
ItemNameVisibilityInfo visibility = (ItemNameVisibilityInfo) caffeineCache.getIfPresent(modelId);
|
||||
if (visibility == null) {
|
||||
visibility = configService.getVisibilityByModelId(modelId);
|
||||
caffeineCache.put(modelId, visibility);
|
||||
}
|
||||
if (!visibility.getBlackMetricNameList().contains(hanlpMapResult.getName())
|
||||
&& !visibility.getBlackDimNameList().contains(hanlpMapResult.getName())) {
|
||||
searchResults.add(searchResult);
|
||||
}
|
||||
}
|
||||
log.info("parseResult:{},dimensionMetricClassIds:{},possibleModels:{}", hanlpMapResult,
|
||||
dimensionMetricClassIds, possibleModels);
|
||||
}
|
||||
log.info("searchMetricAndDimension searchResults:{}", searchResults);
|
||||
return existMetric;
|
||||
}
|
||||
|
||||
private boolean matchCondition(ModelWithSemanticType entry, Set<Long> possibleModels) {
|
||||
if (!(SchemaElementType.METRIC.equals(entry.getSchemaElementType()) || SchemaElementType.DIMENSION.equals(
|
||||
entry.getSchemaElementType()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(possibleModels)) {
|
||||
return true;
|
||||
}
|
||||
return possibleModels.contains(entry.getModel());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.StatisticsDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.repository.StatisticsRepository;
|
||||
import com.tencent.supersonic.chat.server.service.StatisticsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service("statisticsService")
|
||||
@Slf4j
|
||||
public class StatisticsServiceImpl implements StatisticsService {
|
||||
|
||||
private StatisticsRepository statisticsRepository;
|
||||
|
||||
public StatisticsServiceImpl(StatisticsRepository statisticsRepository) {
|
||||
this.statisticsRepository = statisticsRepository;
|
||||
}
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void batchSaveStatistics(List<StatisticsDO> list) {
|
||||
statisticsRepository.batchSaveStatistics(list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.tencent.supersonic.chat.server.service.impl;
|
||||
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.SemanticSchema;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictWord;
|
||||
import com.tencent.supersonic.chat.core.knowledge.builder.WordBuilderFactory;
|
||||
import com.tencent.supersonic.chat.core.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.common.pojo.enums.DictWordType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WordService {
|
||||
|
||||
private List<DictWord> preDictWords = new ArrayList<>();
|
||||
|
||||
public List<DictWord> getAllDictWords() {
|
||||
SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
SemanticSchema semanticSchema = new SemanticSchema(semanticInterpreter.getModelSchema());
|
||||
|
||||
List<DictWord> words = new ArrayList<>();
|
||||
|
||||
addWordsByType(DictWordType.DIMENSION, semanticSchema.getDimensions(), words);
|
||||
addWordsByType(DictWordType.METRIC, semanticSchema.getMetrics(), words);
|
||||
addWordsByType(DictWordType.MODEL, semanticSchema.getModels(), words);
|
||||
addWordsByType(DictWordType.ENTITY, semanticSchema.getEntities(), words);
|
||||
addWordsByType(DictWordType.VALUE, semanticSchema.getDimensionValues(), words);
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
private void addWordsByType(DictWordType value, List<SchemaElement> metas, List<DictWord> natures) {
|
||||
List<DictWord> natureList = WordBuilderFactory.get(value).getDictWords(metas);
|
||||
log.debug("nature type:{} , nature size:{}", value.name(), natureList.size());
|
||||
natures.addAll(natureList);
|
||||
}
|
||||
|
||||
public List<DictWord> getPreDictWords() {
|
||||
return preDictWords;
|
||||
}
|
||||
|
||||
public void setPreDictWords(List<DictWord> preDictWords) {
|
||||
this.preDictWords = preDictWords;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.tencent.supersonic.chat.server.util;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.ADMIN_LOWER;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatAggConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigBaseReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigEditReqReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ChatDetailConfigReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ItemVisibility;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfig;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO;
|
||||
import com.tencent.supersonic.common.pojo.RecordInfo;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import java.util.ArrayList;
|
||||
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.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ChatConfigHelper {
|
||||
|
||||
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);
|
||||
chatConfig.setRecordInfo(recordInfo);
|
||||
chatConfig.setStatus(StatusEnum.ONLINE);
|
||||
return chatConfig;
|
||||
}
|
||||
|
||||
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);
|
||||
chatConfig.setRecordInfo(recordInfo);
|
||||
return chatConfig;
|
||||
}
|
||||
|
||||
public List<Long> generateAllDimIdList(ModelSchema modelSchema) {
|
||||
if (Objects.isNull(modelSchema) || CollectionUtils.isEmpty(modelSchema.getDimensions())) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<Long, List<SchemaElement>> dimIdAndDescPair = modelSchema.getDimensions()
|
||||
.stream().collect(Collectors.groupingBy(SchemaElement::getId));
|
||||
return new ArrayList<>(dimIdAndDescPair.keySet());
|
||||
}
|
||||
|
||||
public List<Long> generateAllMetricIdList(ModelSchema modelSchema) {
|
||||
if (Objects.isNull(modelSchema) || CollectionUtils.isEmpty(modelSchema.getMetrics())) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<Long, List<SchemaElement>> metricIdAndDescPair = modelSchema.getMetrics()
|
||||
.stream().collect(Collectors.groupingBy(SchemaElement::getId));
|
||||
return new ArrayList<>(metricIdAndDescPair.keySet());
|
||||
}
|
||||
|
||||
public ChatConfigDO chatConfig2DO(ChatConfig chatConfig) {
|
||||
ChatConfigDO chatConfigDO = new ChatConfigDO();
|
||||
BeanUtils.copyProperties(chatConfig, chatConfigDO);
|
||||
|
||||
chatConfigDO.setChatAggConfig(JsonUtil.toString(chatConfig.getChatAggConfig()));
|
||||
chatConfigDO.setChatDetailConfig(JsonUtil.toString(chatConfig.getChatDetailConfig()));
|
||||
chatConfigDO.setRecommendedQuestions(JsonUtil.toString(chatConfig.getRecommendedQuestions()));
|
||||
|
||||
if (Objects.isNull(chatConfig.getStatus())) {
|
||||
chatConfigDO.setStatus(null);
|
||||
} else {
|
||||
chatConfigDO.setStatus(chatConfig.getStatus().getCode());
|
||||
}
|
||||
|
||||
chatConfigDO.setCreatedBy(chatConfig.getRecordInfo().getCreatedBy());
|
||||
chatConfigDO.setCreatedAt(chatConfig.getRecordInfo().getCreatedAt());
|
||||
chatConfigDO.setUpdatedBy(chatConfig.getRecordInfo().getUpdatedBy());
|
||||
chatConfigDO.setUpdatedAt(chatConfig.getRecordInfo().getUpdatedAt());
|
||||
|
||||
return chatConfigDO;
|
||||
}
|
||||
|
||||
public ChatConfigResp chatConfigDO2Descriptor(Long modelId, ChatConfigDO chatConfigDO) {
|
||||
ChatConfigResp chatConfigDescriptor = new ChatConfigResp();
|
||||
|
||||
if (Objects.isNull(chatConfigDO)) {
|
||||
// deal empty chatConfigDO
|
||||
return generateEmptyChatConfigResp(modelId);
|
||||
}
|
||||
|
||||
BeanUtils.copyProperties(chatConfigDO, chatConfigDescriptor);
|
||||
|
||||
chatConfigDescriptor.setChatDetailConfig(
|
||||
JsonUtil.toObject(chatConfigDO.getChatDetailConfig(), ChatDetailConfigReq.class));
|
||||
chatConfigDescriptor.setChatAggConfig(
|
||||
JsonUtil.toObject(chatConfigDO.getChatAggConfig(), ChatAggConfigReq.class));
|
||||
chatConfigDescriptor.setRecommendedQuestions(
|
||||
JsonUtil.toList(chatConfigDO.getRecommendedQuestions(), RecommendedQuestionReq.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 modelId) {
|
||||
ChatConfigResp chatConfigResp = new ChatConfigResp();
|
||||
chatConfigResp.setModelId(modelId);
|
||||
chatConfigResp.setChatDetailConfig(generateEmptyChatDetailConfigResp());
|
||||
chatConfigResp.setChatAggConfig(generateEmptyChatAggConfigResp());
|
||||
return chatConfigResp;
|
||||
}
|
||||
|
||||
private ChatDetailConfigReq generateEmptyChatDetailConfigResp() {
|
||||
ChatDetailConfigReq chatDetailConfig = new ChatDetailConfigReq();
|
||||
ItemVisibility visibility = new ItemVisibility();
|
||||
chatDetailConfig.setVisibility(visibility);
|
||||
return chatDetailConfig;
|
||||
}
|
||||
|
||||
private ChatAggConfigReq generateEmptyChatAggConfigResp() {
|
||||
ChatAggConfigReq chatAggConfig = new ChatAggConfigReq();
|
||||
ItemVisibility visibility = new ItemVisibility();
|
||||
chatAggConfig.setVisibility(visibility);
|
||||
return chatAggConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.tencent.supersonic.chat.server.util;
|
||||
|
||||
import com.tencent.supersonic.chat.core.corrector.SemanticCorrector;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.core.mapper.SchemaMapper;
|
||||
import com.tencent.supersonic.chat.core.parser.JavaLLMProxy;
|
||||
import com.tencent.supersonic.chat.core.parser.LLMProxy;
|
||||
import com.tencent.supersonic.chat.core.parser.SemanticParser;
|
||||
import com.tencent.supersonic.chat.core.parser.sql.llm.ModelResolver;
|
||||
import com.tencent.supersonic.chat.server.processor.execute.ExecuteResultProcessor;
|
||||
import com.tencent.supersonic.chat.server.processor.parse.ParseResultProcessor;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
@Slf4j
|
||||
public class ComponentFactory {
|
||||
|
||||
private static List<SchemaMapper> schemaMappers = new ArrayList<>();
|
||||
private static List<SemanticParser> semanticParsers = new ArrayList<>();
|
||||
private static List<SemanticCorrector> semanticCorrectors = new ArrayList<>();
|
||||
private static SemanticInterpreter semanticInterpreter;
|
||||
|
||||
private static LLMProxy llmProxy;
|
||||
private static List<ParseResultProcessor> parseProcessors = new ArrayList<>();
|
||||
private static List<ExecuteResultProcessor> executeProcessors = new ArrayList<>();
|
||||
private static ModelResolver modelResolver;
|
||||
|
||||
public static List<SchemaMapper> getSchemaMappers() {
|
||||
return CollectionUtils.isEmpty(schemaMappers) ? init(SchemaMapper.class, schemaMappers) : schemaMappers;
|
||||
}
|
||||
|
||||
public static List<SemanticParser> getSemanticParsers() {
|
||||
return CollectionUtils.isEmpty(semanticParsers) ? init(SemanticParser.class, semanticParsers) : semanticParsers;
|
||||
}
|
||||
|
||||
public static List<SemanticCorrector> getSemanticCorrectors() {
|
||||
return CollectionUtils.isEmpty(semanticCorrectors) ? init(SemanticCorrector.class,
|
||||
semanticCorrectors) : semanticCorrectors;
|
||||
}
|
||||
|
||||
public static List<ParseResultProcessor> getParseProcessors() {
|
||||
return CollectionUtils.isEmpty(parseProcessors) ? init(ParseResultProcessor.class,
|
||||
parseProcessors) : parseProcessors;
|
||||
}
|
||||
|
||||
public static List<ExecuteResultProcessor> getExecuteProcessors() {
|
||||
return CollectionUtils.isEmpty(executeProcessors)
|
||||
? init(ExecuteResultProcessor.class, executeProcessors) : executeProcessors;
|
||||
}
|
||||
|
||||
public static SemanticInterpreter getSemanticLayer() {
|
||||
if (Objects.isNull(semanticInterpreter)) {
|
||||
semanticInterpreter = init(SemanticInterpreter.class);
|
||||
}
|
||||
return semanticInterpreter;
|
||||
}
|
||||
|
||||
public static LLMProxy getLLMProxy() {
|
||||
//1.Preferentially retrieve from environment variables
|
||||
String llmProxyEnv = System.getenv("llmProxy");
|
||||
if (StringUtils.isNotBlank(llmProxyEnv)) {
|
||||
Map<String, LLMProxy> implementations = ContextUtils.getBeansOfType(LLMProxy.class);
|
||||
llmProxy = implementations.entrySet().stream()
|
||||
.filter(entry -> entry.getKey().equalsIgnoreCase(llmProxyEnv))
|
||||
.map(Map.Entry::getValue)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
//2.default JavaLLMProxy
|
||||
if (Objects.isNull(llmProxy)) {
|
||||
llmProxy = ContextUtils.getBean(JavaLLMProxy.class);
|
||||
}
|
||||
log.info("llmProxy:{}", llmProxy);
|
||||
return llmProxy;
|
||||
}
|
||||
|
||||
public static ModelResolver getModelResolver() {
|
||||
if (Objects.isNull(modelResolver)) {
|
||||
modelResolver = init(ModelResolver.class);
|
||||
}
|
||||
return modelResolver;
|
||||
}
|
||||
|
||||
private static <T> List<T> init(Class<T> factoryType, List list) {
|
||||
list.addAll(SpringFactoriesLoader.loadFactories(factoryType,
|
||||
Thread.currentThread().getContextClassLoader()));
|
||||
return list;
|
||||
}
|
||||
|
||||
private static <T> T init(Class<T> factoryType) {
|
||||
return SpringFactoriesLoader.loadFactories(factoryType,
|
||||
Thread.currentThread().getContextClassLoader()).get(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
package com.tencent.supersonic.chat.server.util;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.UNDERLINE;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.chat.api.pojo.ModelSchema;
|
||||
import com.tencent.supersonic.chat.api.pojo.SchemaElement;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeAdvancedConfig;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
|
||||
import com.tencent.supersonic.chat.api.pojo.response.ChatDefaultRichConfigResp;
|
||||
import com.tencent.supersonic.chat.core.config.DefaultMetric;
|
||||
import com.tencent.supersonic.chat.core.config.Dim4Dict;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictUpdateMode;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValue2DictCommand;
|
||||
import com.tencent.supersonic.chat.core.knowledge.semantic.SemanticInterpreter;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DimValueDO;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import com.tencent.supersonic.headless.api.request.PageDimensionReq;
|
||||
import com.tencent.supersonic.headless.api.response.DimensionResp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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;
|
||||
|
||||
@Component
|
||||
public class DictMetaHelper {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
@Value("${model.internal.metric.suffix:internal_cnt}")
|
||||
private String internalMetricNameSuffix;
|
||||
@Value("${model.internal.day.number:2}")
|
||||
private Integer internalMetricDays;
|
||||
private SemanticInterpreter semanticInterpreter = ComponentFactory.getSemanticLayer();
|
||||
|
||||
public List<DimValueDO> generateDimValueInfo(DimValue2DictCommand dimValue2DictCommend) {
|
||||
List<DimValueDO> dimValueDOList = new ArrayList<>();
|
||||
DictUpdateMode updateMode = dimValue2DictCommend.getUpdateMode();
|
||||
Set<Long> modelIds = new HashSet<>();
|
||||
switch (updateMode) {
|
||||
case OFFLINE_MODEL:
|
||||
modelIds.addAll(dimValue2DictCommend.getModelIds());
|
||||
dimValueDOList = generateDimValueInfoByModel(modelIds);
|
||||
break;
|
||||
case OFFLINE_FULL:
|
||||
List<ModelSchema> modelSchemaDescList = semanticInterpreter.getModelSchema();
|
||||
if (CollectionUtils.isEmpty(modelSchemaDescList)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Map<Long, ModelSchema> modelIdAndDescPair = modelSchemaDescList.stream()
|
||||
.collect(Collectors.toMap(a -> a.getModel().getId(), schema -> schema, (k1, k2) -> k1));
|
||||
if (!CollectionUtils.isEmpty(modelIdAndDescPair)) {
|
||||
modelIds.addAll(modelIdAndDescPair.keySet());
|
||||
dimValueDOList = generateDimValueInfoByModel(modelIds);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case REALTIME_ADD:
|
||||
dimValueDOList = generateDimValueInfoByModelAndDim(dimValue2DictCommend.getModelAndDimPair());
|
||||
break;
|
||||
case NOT_SUPPORT:
|
||||
throw new RuntimeException("illegal parameter for updateMode");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dimValueDOList;
|
||||
}
|
||||
|
||||
private List<DimValueDO> generateDimValueInfoByModelAndDim(Map<Long, List<Long>> modelAndDimMap) {
|
||||
List<DimValueDO> dimValueDOList = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(modelAndDimMap)) {
|
||||
return dimValueDOList;
|
||||
}
|
||||
|
||||
List<ModelSchema> modelSchemaDescList = semanticInterpreter.getModelSchema();
|
||||
if (CollectionUtils.isEmpty(modelSchemaDescList)) {
|
||||
return dimValueDOList;
|
||||
}
|
||||
Map<Long, ModelSchema> modelIdAndDescPair = modelSchemaDescList.stream()
|
||||
.collect(Collectors.toMap(a -> a.getModel().getId(), a -> a, (k1, k2) -> k1));
|
||||
|
||||
for (Long modelId : modelAndDimMap.keySet()) {
|
||||
if (!modelIdAndDescPair.containsKey(modelId)) {
|
||||
continue;
|
||||
}
|
||||
Map<Long, SchemaElement> dimIdAndDescPairAll;
|
||||
dimIdAndDescPairAll = modelIdAndDescPair.get(modelId).getDimensions().stream()
|
||||
.collect(Collectors.toMap(SchemaElement::getId, dimSchemaDesc -> dimSchemaDesc, (k1, k2) -> k1));
|
||||
List<Long> dimIdReq = modelAndDimMap.get(modelId);
|
||||
Map<Long, SchemaElement> dimIdAndDescPairReq = new HashMap<>();
|
||||
for (Long dimId : dimIdReq) {
|
||||
if (dimIdAndDescPairAll.containsKey(dimId)) {
|
||||
dimIdAndDescPairReq.put(dimId, dimIdAndDescPairAll.get(dimId));
|
||||
}
|
||||
}
|
||||
fillDimValueDOList(dimValueDOList, modelId, dimIdAndDescPairReq);
|
||||
}
|
||||
|
||||
return dimValueDOList;
|
||||
}
|
||||
|
||||
private List<DimValueDO> generateDimValueInfoByModel(Set<Long> modelIds) {
|
||||
List<DimValueDO> dimValueDOList = new ArrayList<>();
|
||||
List<ModelSchema> modelSchemaDescList = semanticInterpreter.getModelSchema(new ArrayList<>(modelIds));
|
||||
if (CollectionUtils.isEmpty(modelSchemaDescList)) {
|
||||
return dimValueDOList;
|
||||
}
|
||||
|
||||
modelSchemaDescList.forEach(modelSchemaDesc -> {
|
||||
Map<Long, SchemaElement> dimIdAndDescPair = modelSchemaDesc.getDimensions().stream()
|
||||
.collect(Collectors.toMap(SchemaElement::getId, dimSchemaDesc -> dimSchemaDesc, (k1, k2) -> k1));
|
||||
fillDimValueDOList(dimValueDOList, modelSchemaDesc.getModel().getId(), dimIdAndDescPair);
|
||||
|
||||
});
|
||||
|
||||
return dimValueDOList;
|
||||
}
|
||||
|
||||
private void fillDimValueDOList(List<DimValueDO> dimValueDOList, Long modelId,
|
||||
Map<Long, SchemaElement> dimIdAndDescPair) {
|
||||
ChatConfigRichResp chaConfigRichDesc = configService.getConfigRichInfo(modelId);
|
||||
if (Objects.nonNull(chaConfigRichDesc) && Objects.nonNull(chaConfigRichDesc.getChatAggRichConfig())) {
|
||||
|
||||
ChatDefaultRichConfigResp chatDefaultConfig =
|
||||
chaConfigRichDesc.getChatAggRichConfig().getChatDefaultConfig();
|
||||
|
||||
List<KnowledgeInfoReq> knowledgeAggInfo =
|
||||
chaConfigRichDesc.getChatAggRichConfig().getKnowledgeInfos();
|
||||
|
||||
List<KnowledgeInfoReq> knowledgeDetailInfo =
|
||||
chaConfigRichDesc.getChatDetailRichConfig().getKnowledgeInfos();
|
||||
|
||||
fillKnowledgeDimValue(knowledgeDetailInfo, chatDefaultConfig, dimValueDOList, dimIdAndDescPair, modelId);
|
||||
fillKnowledgeDimValue(knowledgeAggInfo, chatDefaultConfig, dimValueDOList, dimIdAndDescPair, modelId);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void fillKnowledgeDimValue(List<KnowledgeInfoReq> knowledgeInfos,
|
||||
ChatDefaultRichConfigResp chatDefaultConfig,
|
||||
List<DimValueDO> dimValueDOList,
|
||||
Map<Long, SchemaElement> dimIdAndDescPair, Long modelId) {
|
||||
Map<Long, DimensionResp> dimIdAndRespPair = queryDimensionRespByModelId(
|
||||
new ArrayList<>(Arrays.asList(modelId)));
|
||||
if (!CollectionUtils.isEmpty(knowledgeInfos)) {
|
||||
List<Dim4Dict> dimensions = new ArrayList<>();
|
||||
List<DefaultMetric> defaultMetricDescList = new ArrayList<>();
|
||||
knowledgeInfos.stream()
|
||||
.filter(knowledgeInfo -> knowledgeInfo.getSearchEnable()
|
||||
&& !CollectionUtils.isEmpty(dimIdAndDescPair)
|
||||
&& dimIdAndDescPair.containsKey(knowledgeInfo.getItemId()))
|
||||
.forEach(knowledgeInfo -> {
|
||||
SchemaElement dimensionDesc = dimIdAndDescPair.get(knowledgeInfo.getItemId());
|
||||
|
||||
Long dimId = dimensionDesc.getId();
|
||||
String internalMetricName = "";
|
||||
if (Objects.nonNull(dimId)) {
|
||||
String datasourceBizName = queryDataSourceByDimId(dimId);
|
||||
internalMetricName = datasourceBizName + UNDERLINE + internalMetricNameSuffix;
|
||||
}
|
||||
|
||||
if (Objects.isNull(chatDefaultConfig)) {
|
||||
defaultMetricDescList.add(new DefaultMetric(internalMetricName,
|
||||
internalMetricDays, DAY));
|
||||
} else {
|
||||
String metric = internalMetricName;
|
||||
if (!CollectionUtils.isEmpty(chatDefaultConfig.getMetrics())) {
|
||||
metric = chatDefaultConfig.getMetrics().get(0).getBizName();
|
||||
}
|
||||
defaultMetricDescList.add(new DefaultMetric(metric,
|
||||
chatDefaultConfig.getUnit(), chatDefaultConfig.getPeriod()));
|
||||
|
||||
}
|
||||
|
||||
String bizName = dimensionDesc.getBizName();
|
||||
Dim4Dict dim4Dict = new Dim4Dict();
|
||||
dim4Dict.setDimId(knowledgeInfo.getItemId());
|
||||
dim4Dict.setBizName(bizName);
|
||||
if (Objects.nonNull(knowledgeInfo.getKnowledgeAdvancedConfig())) {
|
||||
KnowledgeAdvancedConfig knowledgeAdvancedConfig
|
||||
= knowledgeInfo.getKnowledgeAdvancedConfig();
|
||||
BeanUtils.copyProperties(knowledgeAdvancedConfig, dim4Dict);
|
||||
|
||||
if (Objects.nonNull(dimIdAndRespPair)
|
||||
&& dimIdAndRespPair.containsKey(dim4Dict.getDimId())) {
|
||||
String datasourceFilterSql = dimIdAndRespPair.get(
|
||||
dim4Dict.getDimId()).getModelFilterSql();
|
||||
if (StringUtils.isNotEmpty(datasourceFilterSql)) {
|
||||
dim4Dict.getRuleList().add(datasourceFilterSql);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
dimensions.add(dim4Dict);
|
||||
|
||||
});
|
||||
|
||||
if (!CollectionUtils.isEmpty(dimensions)) {
|
||||
DimValueDO dimValueDO = new DimValueDO()
|
||||
.setModelId(modelId)
|
||||
.setDefaultMetricIds(defaultMetricDescList)
|
||||
.setDimensions(dimensions);
|
||||
dimValueDOList.add(dimValueDO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Long, DimensionResp> queryDimensionRespByModelId(List<Long> modelIds) {
|
||||
Map<Long, DimensionResp> dimIdAndRespPair = new HashMap<>();
|
||||
PageDimensionReq pageDimensionCmd = new PageDimensionReq();
|
||||
pageDimensionCmd.setModelIds(modelIds);
|
||||
PageInfo<DimensionResp> dimensionPage = semanticInterpreter.getDimensionPage(pageDimensionCmd);
|
||||
if (Objects.nonNull(dimensionPage) && !CollectionUtils.isEmpty(dimensionPage.getList())) {
|
||||
List<DimensionResp> dimList = dimensionPage.getList();
|
||||
dimIdAndRespPair = dimList.stream().collect(Collectors.toMap(DimensionResp::getId, v -> v, (v1, v2) -> v2));
|
||||
}
|
||||
return dimIdAndRespPair;
|
||||
}
|
||||
|
||||
private String queryDataSourceByDimId(Long id) {
|
||||
PageDimensionReq pageDimensionCmd = new PageDimensionReq();
|
||||
pageDimensionCmd.setId(id.toString());
|
||||
PageInfo<DimensionResp> dimensionPage = semanticInterpreter.getDimensionPage(pageDimensionCmd);
|
||||
if (Objects.nonNull(dimensionPage) && !CollectionUtils.isEmpty(dimensionPage.getList())) {
|
||||
List<DimensionResp> list = dimensionPage.getList();
|
||||
return list.get(0).getModelBizName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.tencent.supersonic.chat.server.util;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DictConfig;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValue2DictCommand;
|
||||
import com.tencent.supersonic.chat.core.knowledge.DimValueInfo;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictConfDO;
|
||||
import com.tencent.supersonic.chat.server.persistence.dataobject.DictTaskDO;
|
||||
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class DictTaskConverter {
|
||||
|
||||
private static String dateTimeFormatter = "yyyyMMddHHmmss";
|
||||
|
||||
public static DictTaskDO generateDimValueDictTaskDO(DimValue2DictCommand dimValue2DictCommend, User user) {
|
||||
DictTaskDO taskPO = new DictTaskDO();
|
||||
Date createAt = new Date();
|
||||
String date = DateTimeFormatter.ofPattern(dateTimeFormatter)
|
||||
.format(createAt.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
|
||||
String creator = Strings.isNullOrEmpty(user.getName()) ? "" : user.getName();
|
||||
String updateMode = dimValue2DictCommend.getUpdateMode().getValue();
|
||||
String name = String.format("DimValue_dic_%s_%s_%s", updateMode, creator, date);
|
||||
taskPO.setName(name);
|
||||
|
||||
taskPO.setCreatedAt(createAt);
|
||||
taskPO.setCommand(JsonUtil.toString(dimValue2DictCommend));
|
||||
taskPO.setStatus(TaskStatusEnum.PENDING.getCode());
|
||||
taskPO.setCreatedBy(creator);
|
||||
|
||||
return taskPO;
|
||||
}
|
||||
|
||||
public static DictConfig dictConfPO2Config(DictConfDO dictConfDO) {
|
||||
DictConfig dictConfig = new DictConfig();
|
||||
dictConfig.setModelId(dictConfDO.getModelId());
|
||||
List<DimValueInfo> dimValueInfos = JsonUtil.toList(dictConfDO.getDimValueInfos(), DimValueInfo.class);
|
||||
dictConfig.setDimValueInfoList(dimValueInfos);
|
||||
return dictConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.tencent.supersonic.chat.server.util;
|
||||
|
||||
import com.tencent.supersonic.chat.server.config.ChatConfig;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
public class VisibilityEvent extends ApplicationEvent {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private ChatConfig chatConfig;
|
||||
|
||||
public VisibilityEvent(Object source, ChatConfig chatConfig) {
|
||||
super(source);
|
||||
this.chatConfig = chatConfig;
|
||||
}
|
||||
|
||||
public void setChatConfig(ChatConfig chatConfig) {
|
||||
this.chatConfig = chatConfig;
|
||||
}
|
||||
|
||||
public ChatConfig getChatConfig() {
|
||||
return chatConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.tencent.supersonic.chat.server.util;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.tencent.supersonic.chat.api.pojo.request.ItemNameVisibilityInfo;
|
||||
import com.tencent.supersonic.chat.server.service.ConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class VisibilityListener implements ApplicationListener<VisibilityEvent> {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("searchCaffeineCache")
|
||||
private Cache<Long, Object> caffeineCache;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(VisibilityEvent event) {
|
||||
log.info("visibility has changed,so update cache!");
|
||||
ItemNameVisibilityInfo itemNameVisibility = configService.getItemNameVisibility(event.getChatConfig());
|
||||
log.info("itemNameVisibility :{}", itemNameVisibility);
|
||||
caffeineCache.put(event.getChatConfig().getModelId(), itemNameVisibility);
|
||||
}
|
||||
}
|
||||
303
chat/server/src/main/resources/mapper/AgentDOMapper.xml
Normal file
303
chat/server/src/main/resources/mapper/AgentDOMapper.xml
Normal file
@@ -0,0 +1,303 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.tencent.supersonic.chat.server.persistence.mapper.AgentDOMapper">
|
||||
<resultMap id="BaseResultMap" type="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO">
|
||||
<id column="id" jdbcType="INTEGER" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="description" jdbcType="VARCHAR" property="description" />
|
||||
<result column="status" jdbcType="INTEGER" property="status" />
|
||||
<result column="examples" jdbcType="VARCHAR" property="examples" />
|
||||
<result column="config" jdbcType="VARCHAR" property="config" />
|
||||
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
|
||||
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
|
||||
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
|
||||
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
|
||||
<result column="enable_search" jdbcType="INTEGER" property="enableSearch" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Update_By_Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, name, description, status, examples, config, created_by, created_at, updated_by,
|
||||
updated_at, enable_search
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDOExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from s2_agent
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
<if test="limitStart != null and limitStart>=0">
|
||||
limit #{limitStart} , #{limitEnd}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from s2_agent
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</select>
|
||||
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
|
||||
delete from s2_agent
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</delete>
|
||||
<insert id="insert" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO">
|
||||
insert into s2_agent (id, name, description,
|
||||
status, examples, config,
|
||||
created_by, created_at, updated_by,
|
||||
updated_at, enable_search)
|
||||
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
|
||||
#{status,jdbcType=INTEGER}, #{examples,jdbcType=VARCHAR}, #{config,jdbcType=VARCHAR},
|
||||
#{createdBy,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedBy,jdbcType=VARCHAR},
|
||||
#{updatedAt,jdbcType=TIMESTAMP}, #{enableSearch,jdbcType=INTEGER})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO">
|
||||
insert into s2_agent
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
id,
|
||||
</if>
|
||||
<if test="name != null">
|
||||
name,
|
||||
</if>
|
||||
<if test="description != null">
|
||||
description,
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status,
|
||||
</if>
|
||||
<if test="examples != null">
|
||||
examples,
|
||||
</if>
|
||||
<if test="config != null">
|
||||
config,
|
||||
</if>
|
||||
<if test="createdBy != null">
|
||||
created_by,
|
||||
</if>
|
||||
<if test="createdAt != null">
|
||||
created_at,
|
||||
</if>
|
||||
<if test="updatedBy != null">
|
||||
updated_by,
|
||||
</if>
|
||||
<if test="updatedAt != null">
|
||||
updated_at,
|
||||
</if>
|
||||
<if test="enableSearch != null">
|
||||
enable_search,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
#{id,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="name != null">
|
||||
#{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="description != null">
|
||||
#{description,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
#{status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="examples != null">
|
||||
#{examples,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="config != null">
|
||||
#{config,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createdBy != null">
|
||||
#{createdBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createdAt != null">
|
||||
#{createdAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="updatedBy != null">
|
||||
#{updatedBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="updatedAt != null">
|
||||
#{updatedAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="enableSearch != null">
|
||||
#{enableSearch,jdbcType=INTEGER},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDOExample" resultType="java.lang.Long">
|
||||
select count(*) from s2_agent
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update s2_agent
|
||||
<set>
|
||||
<if test="record.id != null">
|
||||
id = #{record.id,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.name != null">
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.description != null">
|
||||
description = #{record.description,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.status != null">
|
||||
status = #{record.status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.examples != null">
|
||||
examples = #{record.examples,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.config != null">
|
||||
config = #{record.config,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createdBy != null">
|
||||
created_by = #{record.createdBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createdAt != null">
|
||||
created_at = #{record.createdAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="record.updatedBy != null">
|
||||
updated_by = #{record.updatedBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.updatedAt != null">
|
||||
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="record.enableSearch != null">
|
||||
enable_search = #{record.enableSearch,jdbcType=INTEGER},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update s2_agent
|
||||
set id = #{record.id,jdbcType=INTEGER},
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
description = #{record.description,jdbcType=VARCHAR},
|
||||
status = #{record.status,jdbcType=INTEGER},
|
||||
examples = #{record.examples,jdbcType=VARCHAR},
|
||||
config = #{record.config,jdbcType=VARCHAR},
|
||||
created_by = #{record.createdBy,jdbcType=VARCHAR},
|
||||
created_at = #{record.createdAt,jdbcType=TIMESTAMP},
|
||||
updated_by = #{record.updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
|
||||
enable_search = #{record.enableSearch,jdbcType=INTEGER}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO">
|
||||
update s2_agent
|
||||
<set>
|
||||
<if test="name != null">
|
||||
name = #{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="description != null">
|
||||
description = #{description,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="examples != null">
|
||||
examples = #{examples,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="config != null">
|
||||
config = #{config,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createdBy != null">
|
||||
created_by = #{createdBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createdAt != null">
|
||||
created_at = #{createdAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="updatedBy != null">
|
||||
updated_by = #{updatedBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="updatedAt != null">
|
||||
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="enableSearch != null">
|
||||
enable_search = #{enableSearch,jdbcType=INTEGER},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO">
|
||||
update s2_agent
|
||||
set name = #{name,jdbcType=VARCHAR},
|
||||
description = #{description,jdbcType=VARCHAR},
|
||||
status = #{status,jdbcType=INTEGER},
|
||||
examples = #{examples,jdbcType=VARCHAR},
|
||||
config = #{config,jdbcType=VARCHAR},
|
||||
created_by = #{createdBy,jdbcType=VARCHAR},
|
||||
created_at = #{createdAt,jdbcType=TIMESTAMP},
|
||||
updated_by = #{updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
|
||||
enable_search = #{enableSearch,jdbcType=INTEGER}
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</update>
|
||||
</mapper>
|
||||
97
chat/server/src/main/resources/mapper/ChatConfigMapper.xml
Normal file
97
chat/server/src/main/resources/mapper/ChatConfigMapper.xml
Normal file
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
|
||||
<mapper namespace="com.tencent.supersonic.chat.server.persistence.mapper.ChatConfigMapper">
|
||||
|
||||
<resultMap id="chaConfigDO"
|
||||
type="com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO">
|
||||
<id column="id" property="id"/>
|
||||
<result column="model_id" property="modelId"/>
|
||||
<result column="chat_detail_config" property="chatDetailConfig"/>
|
||||
<result column="chat_agg_config" property="chatAggConfig"/>
|
||||
<result column="recommended_questions" property="recommendedQuestions"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="llm_examples" property="llmExamples"/>
|
||||
<result column="created_by" property="createdBy"/>
|
||||
<result column="updated_by" property="updatedBy"/>
|
||||
<result column="created_at" property="createdAt"/>
|
||||
<result column="updated_at" property="updatedAt"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="addConfig"
|
||||
parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO"
|
||||
useGeneratedKeys="true" keyProperty="id">
|
||||
insert into s2_chat_config
|
||||
(
|
||||
model_id, `chat_detail_config`, chat_agg_config, recommended_questions, status, llm_examples, created_by, updated_by, created_at, updated_at
|
||||
)
|
||||
values
|
||||
(
|
||||
#{modelId}, #{chatDetailConfig}, #{chatAggConfig}, #{recommendedQuestions}, #{status}, #{llmExamples}, #{createdBy}, #{updatedBy}, #{createdAt}, #{updatedAt}
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
||||
<update id="editConfig">
|
||||
update s2_chat_config
|
||||
<set>
|
||||
`updated_at` = #{updatedAt} ,
|
||||
<if test="chatDetailConfig != null and chatDetailConfig != ''">
|
||||
`chat_detail_config` = #{chatDetailConfig} ,
|
||||
</if>
|
||||
<if test="chatAggConfig != null and chatAggConfig != ''">
|
||||
chat_agg_config = #{chatAggConfig} ,
|
||||
</if>
|
||||
<if test="recommendedQuestions != null and recommendedQuestions != ''">
|
||||
recommended_questions = #{recommendedQuestions} ,
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
status = #{status} ,
|
||||
</if>
|
||||
<if test="updatedBy != null and updatedBy != ''">
|
||||
updated_by = #{updatedBy} ,
|
||||
</if>
|
||||
<if test="llmExamples != null and llmExamples != ''">
|
||||
llm_examples = #{llmExamples} ,
|
||||
</if>
|
||||
</set>
|
||||
|
||||
<where>
|
||||
<if test="id != null and id != ''">
|
||||
id = #{id}
|
||||
</if>
|
||||
<if test="modelId != null and modelId != ''">
|
||||
and model_id = #{modelId}
|
||||
</if>
|
||||
</where>
|
||||
</update>
|
||||
|
||||
<select id="search" resultMap="chaConfigDO">
|
||||
select *
|
||||
from s2_chat_config
|
||||
<where>
|
||||
<if test="id != null and id != ''">
|
||||
id = #{id}
|
||||
</if>
|
||||
<if test="modelId != null and modelId != ''">
|
||||
and model_id = #{modelId}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
and status = #{status}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
</select>
|
||||
|
||||
<select id="fetchConfigByModelId" resultMap="chaConfigDO">
|
||||
select *
|
||||
from s2_chat_config
|
||||
where model_id = #{modelId}
|
||||
and status != 3
|
||||
order by updated_at desc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user