10 Commits

Author SHA1 Message Date
beat4ocean
4b51dc6cca Merge f3ffcb94f1 into d2a43a99c8 2025-03-23 07:51:23 +00:00
beat4ocean
f3ffcb94f1 Merge branch 'tencentmusic:master' into master 2025-03-23 15:51:20 +08:00
jerryjzhang
d2a43a99c8 (feature)(headless)Support offset clause in struct query.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-03-23 14:30:56 +08:00
iridescentpeo
db8f340e2d 修复同一模型被多个数据集引用时: (#2183) 2025-03-23 14:14:08 +08:00
beat4ocean
de427b8093 Merge branch 'tencentmusic:master' into master 2025-03-19 12:23:39 +08:00
beat4ocean
82c188c17a Merge branch 'tencentmusic:master' into master 2025-03-17 08:53:42 +08:00
beat4ocean
54e3e1487b [fix][headless-fe] Property 'nameEn' does not exist on type 'ColumnType'. 2025-03-14 20:58:15 +08:00
beat4ocean
c2adb3314d Merge branch 'tencentmusic:master' into master 2025-03-14 09:56:00 +08:00
beat4ocean
74f4732401 [fix][chat]Fix dashboard display issue when categoryColumnName and dateColumnName are identical.
(cherry picked from commit 738093bc88)
2025-03-13 13:57:19 +08:00
beat4ocean
2003c32c96 [Fix][Chat]Fix time granularity bug in model editing and dashboard display.
(cherry picked from commit b6d1525daa)
2025-03-13 13:57:18 +08:00
12 changed files with 68 additions and 52 deletions

View File

@@ -49,7 +49,8 @@ public class EmbeddingServiceImpl implements EmbeddingService {
try { try {
EmbeddingModel embeddingModel = ModelProvider.getEmbeddingModel(); EmbeddingModel embeddingModel = ModelProvider.getEmbeddingModel();
Embedding embedding = embeddingModel.embed(question).content(); Embedding embedding = embeddingModel.embed(question).content();
boolean existSegment = existSegment(collectionName,embeddingStore, query, embedding); boolean existSegment =
existSegment(collectionName, embeddingStore, query, embedding);
if (existSegment) { if (existSegment) {
continue; continue;
} }
@@ -62,8 +63,8 @@ public class EmbeddingServiceImpl implements EmbeddingService {
} }
} }
private boolean existSegment(String collectionName,EmbeddingStore embeddingStore, TextSegment query, private boolean existSegment(String collectionName, EmbeddingStore embeddingStore,
Embedding embedding) { TextSegment query, Embedding embedding) {
String queryId = TextSegmentConvert.getQueryId(query); String queryId = TextSegmentConvert.getQueryId(query);
if (queryId == null) { if (queryId == null) {
return false; return false;

View File

@@ -30,6 +30,7 @@ public class QueryDataSetReq {
private List<Filter> metricFilters = new ArrayList<>(); private List<Filter> metricFilters = new ArrayList<>();
private DateConf dateInfo; private DateConf dateInfo;
private Long limit = 2000L; private Long limit = 2000L;
private Long offset = 0L;
private QueryType queryType = QueryType.DETAIL; private QueryType queryType = QueryType.DETAIL;
private boolean innerLayerNative = false; private boolean innerLayerNative = false;
} }

View File

@@ -3,11 +3,7 @@ package com.tencent.supersonic.headless.api.pojo.request;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.tencent.supersonic.common.jsqlparser.SqlAddHelper; import com.tencent.supersonic.common.jsqlparser.SqlAddHelper;
import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper; import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper;
import com.tencent.supersonic.common.pojo.Aggregator; import com.tencent.supersonic.common.pojo.*;
import com.tencent.supersonic.common.pojo.Constants;
import com.tencent.supersonic.common.pojo.DateConf;
import com.tencent.supersonic.common.pojo.Filter;
import com.tencent.supersonic.common.pojo.Order;
import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum; import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum;
import com.tencent.supersonic.common.pojo.enums.QueryType; import com.tencent.supersonic.common.pojo.enums.QueryType;
import com.tencent.supersonic.common.util.ContextUtils; import com.tencent.supersonic.common.util.ContextUtils;
@@ -25,12 +21,7 @@ import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.GroupByElement; import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.statement.select.Limit;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectItem;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -52,6 +43,7 @@ public class QueryStructReq extends SemanticQueryReq {
private List<Filter> metricFilters = new ArrayList<>(); private List<Filter> metricFilters = new ArrayList<>();
private DateConf dateInfo; private DateConf dateInfo;
private long limit = Constants.DEFAULT_DETAIL_LIMIT; private long limit = Constants.DEFAULT_DETAIL_LIMIT;
private long offset;
private QueryType queryType = QueryType.DETAIL; private QueryType queryType = QueryType.DETAIL;
private boolean convertToSql = true; private boolean convertToSql = true;
@@ -170,12 +162,15 @@ public class QueryStructReq extends SemanticQueryReq {
// 5. Set the limit clause // 5. Set the limit clause
plainSelect.setLimit(buildLimit(queryStructReq)); plainSelect.setLimit(buildLimit(queryStructReq));
// 6. Set having clause // 6. Set the offset clause
plainSelect.setOffset(buildOffset(queryStructReq));
// 7. Set the having clause
plainSelect.setHaving(buildHavingClause(queryStructReq)); plainSelect.setHaving(buildHavingClause(queryStructReq));
select.setSelect(plainSelect); select.setSelect(plainSelect);
// 6. Set where clause // 8. Set the where clause
return addWhereClauses(select.toString(), queryStructReq, isBizName); return addWhereClauses(select.toString(), queryStructReq, isBizName);
} }
@@ -262,6 +257,15 @@ public class QueryStructReq extends SemanticQueryReq {
return limit; return limit;
} }
private Offset buildOffset(QueryStructReq queryStructReq) {
if (Objects.isNull(queryStructReq.getOffset())) {
return null;
}
Offset offset = new Offset();
offset.setOffset(new LongValue(queryStructReq.getOffset()));
return offset;
}
private String addWhereClauses(String sql, QueryStructReq queryStructReq, boolean isBizName) private String addWhereClauses(String sql, QueryStructReq queryStructReq, boolean isBizName)
throws JSQLParserException { throws JSQLParserException {
SqlFilterUtils sqlFilterUtils = ContextUtils.getBean(SqlFilterUtils.class); SqlFilterUtils sqlFilterUtils = ContextUtils.getBean(SqlFilterUtils.class);

View File

@@ -22,4 +22,9 @@ public abstract class MapResult implements Serializable {
return this.getMapKey().equals(otherResult.getMapKey()) return this.getMapKey().equals(otherResult.getMapKey())
&& this.similarity < otherResult.similarity; && this.similarity < otherResult.similarity;
} }
public Boolean lessOrEqualSimilar(MapResult otherResult) {
return this.getMapKey().equals(otherResult.getMapKey())
&& this.similarity <= otherResult.similarity;
}
} }

View File

@@ -75,6 +75,8 @@ public class MetaEmbeddingService {
return dataSetIds.stream().map(dataSetId -> { return dataSetIds.stream().map(dataSetId -> {
Retrieval newRetrieval = new Retrieval(); Retrieval newRetrieval = new Retrieval();
BeanUtils.copyProperties(retrieval, newRetrieval); BeanUtils.copyProperties(retrieval, newRetrieval);
HashMap<String, Object> newMetadata = new HashMap<>(retrieval.getMetadata());
newRetrieval.setMetadata(newMetadata);
newRetrieval.getMetadata().putIfAbsent("dataSetId", newRetrieval.getMetadata().putIfAbsent("dataSetId",
dataSetId + Constants.UNDERLINE); dataSetId + Constants.UNDERLINE);
return newRetrieval; return newRetrieval;

View File

@@ -56,7 +56,7 @@ public abstract class BaseMatchStrategy<T extends MapResult> implements MatchStr
for (T oneRoundResult : oneRoundResults) { for (T oneRoundResult : oneRoundResults) {
if (existResults.contains(oneRoundResult)) { if (existResults.contains(oneRoundResult)) {
boolean isDeleted = existResults.removeIf(existResult -> { boolean isDeleted = existResults.removeIf(existResult -> {
boolean delete = existResult.lessSimilar(oneRoundResult); boolean delete = existResult.lessOrEqualSimilar(oneRoundResult);
if (delete) { if (delete) {
log.debug("deleted existResult:{}", existResult); log.debug("deleted existResult:{}", existResult);
} }

View File

@@ -59,7 +59,8 @@ public class ParserConfig extends ParameterConfig {
@Override @Override
public List<Parameter> getSysParameters() { public List<Parameter> getSysParameters() {
return Lists.newArrayList(PARSER_LINKING_VALUE_ENABLE, PARSER_RULE_CORRECTOR_ENABLE, PARSER_FEW_SHOT_NUMBER, return Lists.newArrayList(PARSER_LINKING_VALUE_ENABLE, PARSER_RULE_CORRECTOR_ENABLE,
PARSER_SELF_CONSISTENCY_NUMBER, PARSER_SHOW_COUNT, PARSER_FIELDS_COUNT_THRESHOLD); PARSER_FEW_SHOT_NUMBER, PARSER_SELF_CONSISTENCY_NUMBER, PARSER_SHOW_COUNT,
PARSER_FIELDS_COUNT_THRESHOLD);
} }
} }

View File

@@ -20,6 +20,7 @@ public class StructQuery {
private List<Filter> metricFilters = new ArrayList(); private List<Filter> metricFilters = new ArrayList();
private DateConf dateInfo; private DateConf dateInfo;
private Long limit = 2000L; private Long limit = 2000L;
private Long offset = 0L;
private QueryType queryType; private QueryType queryType;
private List<Param> params = new ArrayList<>(); private List<Param> params = new ArrayList<>();
} }

View File

@@ -420,7 +420,7 @@ const ChatItem: React.FC<Props> = ({
if (!!queryResults) { if (!!queryResults) {
const exportData = queryResults.map(item => { const exportData = queryResults.map(item => {
return Object.keys(item).reduce((result, key) => { return Object.keys(item).reduce((result, key) => {
const columnName = queryColumns?.find(column => column.nameEn === key)?.name || key; const columnName = queryColumns?.find(column => column.name === key)?.name || key;
result[columnName] = item[key]; result[columnName] = item[key];
return result; return result;
}, {}); }, {});

View File

@@ -48,12 +48,13 @@ const MetricTrend: React.FC<Props> = ({
const { queryColumns, queryResults, aggregateInfo, entityInfo, chatContext } = data; const { queryColumns, queryResults, aggregateInfo, entityInfo, chatContext } = data;
const [chartType, setChartType] = useState('line'); const [chartType, setChartType] = useState('line');
const dateField: any = queryColumns?.find( const dateField = queryColumns?.find(
(column: any) => column.showType === 'DATE' || column.type === 'DATE' (column: any) => column.showType === 'DATE' || column.type === 'DATE'
); );
const dateColumnName = dateField?.bizName || ''; const dateColumnName = dateField?.bizName || '';
const categoryColumnName = let categoryColumnName =
queryColumns?.find((column: any) => column.showType === 'CATEGORY')?.bizName || ''; queryColumns?.find((column: any) => column.showType === 'CATEGORY')?.bizName || '';
categoryColumnName = categoryColumnName === dateColumnName ? '' : categoryColumnName;
const metricFields = queryColumns?.filter((column: any) => column.showType === 'NUMBER'); const metricFields = queryColumns?.filter((column: any) => column.showType === 'NUMBER');
const currentMetricField = queryColumns?.find((column: any) => column.showType === 'NUMBER'); const currentMetricField = queryColumns?.find((column: any) => column.showType === 'NUMBER');
@@ -80,11 +81,11 @@ const MetricTrend: React.FC<Props> = ({
<MetricInfo aggregateInfo={aggregateInfo} currentMetricField={currentMetricField} /> <MetricInfo aggregateInfo={aggregateInfo} currentMetricField={currentMetricField} />
)} )}
<div className={`${prefixCls}-select-options`}> <div className={`${prefixCls}-select-options`}>
<DateOptions {/*<DateOptions*/}
chatContext={chatContext} {/* chatContext={chatContext}*/}
currentDateOption={currentDateOption} {/* currentDateOption={currentDateOption}*/}
onSelectDateOption={onSelectDateOption} {/* onSelectDateOption={onSelectDateOption}*/}
/> {/*/>*/}
<div> <div>
<Select <Select
defaultValue="line" defaultValue="line"

View File

@@ -8,7 +8,7 @@ import { ISemantic } from '../../data';
import { import {
AGG_OPTIONS, AGG_OPTIONS,
DATE_FORMATTER, DATE_FORMATTER,
DATE_OPTIONS, // DATE_OPTIONS,
DIM_OPTIONS, DIM_OPTIONS,
EnumDataSourceType, EnumDataSourceType,
EnumModelDataType, EnumModelDataType,
@@ -275,7 +275,7 @@ const ModelFieldForm: React.FC<Props> = ({
} }
} }
if ([EnumDataSourceType.TIME, EnumDataSourceType.PARTITION_TIME].includes(type)) { if ([EnumDataSourceType.TIME, EnumDataSourceType.PARTITION_TIME].includes(type)) {
const { dateFormat, timeGranularity } = record; const { dateFormat } = record;
const dateFormatterOptions = const dateFormatterOptions =
type === EnumDataSourceType.PARTITION_TIME ? PARTITION_TIME_FORMATTER : DATE_FORMATTER; type === EnumDataSourceType.PARTITION_TIME ? PARTITION_TIME_FORMATTER : DATE_FORMATTER;
@@ -302,25 +302,25 @@ const ModelFieldForm: React.FC<Props> = ({
<ExclamationCircleOutlined /> <ExclamationCircleOutlined />
</Tooltip> </Tooltip>
</Space> </Space>
<Space> {/*<Space>*/}
<span>:</span> {/* <span>时间粒度:</span>*/}
<Select {/* <Select*/}
placeholder="时间粒度" {/* placeholder="时间粒度"*/}
value={timeGranularity === '' ? undefined : timeGranularity} {/* value={timeGranularity === '' ? undefined : timeGranularity}*/}
onChange={(value) => { {/* onChange={(value) => {*/}
handleFieldChange(record, 'timeGranularity', value); {/* handleFieldChange(record, 'timeGranularity', value);*/}
}} {/* }}*/}
defaultValue={timeGranularity === '' ? undefined : DATE_OPTIONS[0]} {/* defaultValue={timeGranularity === '' ? undefined : DATE_OPTIONS[0]}*/}
style={{ minWidth: 180 }} {/* style={{ minWidth: 180 }}*/}
allowClear {/* allowClear*/}
> {/* >*/}
{DATE_OPTIONS.map((item) => ( {/* {DATE_OPTIONS.map((item) => (*/}
<Option key={item} value={item}> {/* <Option key={item} value={item}>*/}
{item} {/* {item}*/}
</Option> {/* </Option>*/}
))} {/* ))}*/}
</Select> {/* </Select>*/}
</Space> {/*</Space>*/}
</Space> </Space>
); );
} }