fix: improve redis recommendation fuzzy fallback handling
- Preserve level continuation marker when trimming recommendation terms - Add group fallback for config and measurement typo inputs - Validate fuzzy exact continuation with redis set membership - Use local nspath set for local fuzzy member checks - Avoid returning continuation marker for exact measurement tag matches - Add tests for fuzzy continuation and mismatch fallback behavior
This commit is contained in:
parent
578f805b57
commit
a5e8c2ba4e
|
|
@ -418,6 +418,15 @@ func trimRecommendTerms(recommends []string, offset int) []string {
|
||||||
seen := make(map[string]struct{})
|
seen := make(map[string]struct{})
|
||||||
|
|
||||||
for _, recommend := range recommends {
|
for _, recommend := range recommends {
|
||||||
|
if recommend == "." {
|
||||||
|
if _, exists := seen[recommend]; exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[recommend] = struct{}{}
|
||||||
|
resultRecommends = append(resultRecommends, recommend)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
recommendRunes := []rune(recommend)
|
recommendRunes := []rune(recommend)
|
||||||
if offset > len(recommendRunes) {
|
if offset > len(recommendRunes) {
|
||||||
continue
|
continue
|
||||||
|
|
@ -530,7 +539,7 @@ func fallbackConfigByInput(ctx context.Context, rdb *redis.Client, allSetKey str
|
||||||
searchInput := inputSlice[len(inputSlice)-1]
|
searchInput := inputSlice[len(inputSlice)-1]
|
||||||
matchedMembers, matchedInput := filterMembersByTrimmedPrefix(members, searchInput)
|
matchedMembers, matchedInput := filterMembersByTrimmedPrefix(members, searchInput)
|
||||||
if len(matchedMembers) == 0 {
|
if len(matchedMembers) == 0 {
|
||||||
return []string{}, 0, nil
|
return fallbackConfigGroupByInput(ctx, rdb, recommendLenType, inputSlice, members)
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixTokens := inputSlice[:len(inputSlice)-1]
|
prefixTokens := inputSlice[:len(inputSlice)-1]
|
||||||
|
|
@ -542,6 +551,16 @@ func fallbackConfigByInput(ctx context.Context, rdb *redis.Client, allSetKey str
|
||||||
return recommends, fuzzyRecommendOffset(strings.Join(prefixTokens, "."), matchedInput), nil
|
return recommends, fuzzyRecommendOffset(strings.Join(prefixTokens, "."), matchedInput), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fallbackConfigGroupByInput(ctx context.Context, rdb *redis.Client, recommendLenType string, inputSlice []string, members []string) ([]string, int, error) {
|
||||||
|
recommends := combineQueryResultByInput(constants.ConfigRecommendHierarchyType, recommendLenType, inputSlice, members)
|
||||||
|
recommends = confirmConfigRecommendResultsByHash(ctx, rdb, inputSlice, members, recommends)
|
||||||
|
if len(recommends) == 0 {
|
||||||
|
return []string{}, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return recommends, recommendPrefixOffset(inputSlice[:len(inputSlice)-1]), nil
|
||||||
|
}
|
||||||
|
|
||||||
func fallbackMeasByInput(ctx context.Context, rdb *redis.Client, allSetKey string, recommendLenType string, inputSlice []string) ([]string, int, error) {
|
func fallbackMeasByInput(ctx context.Context, rdb *redis.Client, allSetKey string, recommendLenType string, inputSlice []string) ([]string, int, error) {
|
||||||
members, err := rdb.SMembers(ctx, allSetKey).Result()
|
members, err := rdb.SMembers(ctx, allSetKey).Result()
|
||||||
if err != nil && err != redis.Nil {
|
if err != nil && err != redis.Nil {
|
||||||
|
|
@ -551,7 +570,7 @@ func fallbackMeasByInput(ctx context.Context, rdb *redis.Client, allSetKey strin
|
||||||
searchInput := inputSlice[len(inputSlice)-1]
|
searchInput := inputSlice[len(inputSlice)-1]
|
||||||
matchedMembers, matchedInput := filterMembersByTrimmedPrefix(members, searchInput)
|
matchedMembers, matchedInput := filterMembersByTrimmedPrefix(members, searchInput)
|
||||||
if len(matchedMembers) == 0 {
|
if len(matchedMembers) == 0 {
|
||||||
return []string{}, 0, nil
|
return fallbackMeasGroupByInput(ctx, rdb, recommendLenType, inputSlice)
|
||||||
}
|
}
|
||||||
|
|
||||||
recommends := combineQueryResultByInput(constants.MeasTagRecommendHierarchyType, recommendLenType, inputSlice, matchedMembers)
|
recommends := combineQueryResultByInput(constants.MeasTagRecommendHierarchyType, recommendLenType, inputSlice, matchedMembers)
|
||||||
|
|
@ -563,6 +582,27 @@ func fallbackMeasByInput(ctx context.Context, rdb *redis.Client, allSetKey strin
|
||||||
return recommends, fuzzyRecommendOffset(strings.Join(inputSlice[:len(inputSlice)-1], "."), matchedInput), nil
|
return recommends, fuzzyRecommendOffset(strings.Join(inputSlice[:len(inputSlice)-1], "."), matchedInput), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fallbackMeasGroupByInput(ctx context.Context, rdb *redis.Client, recommendLenType string, inputSlice []string) ([]string, int, error) {
|
||||||
|
compTag, _, ok := recommendGroupTokens(inputSlice)
|
||||||
|
if !ok {
|
||||||
|
return []string{}, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
queryKey := getSpecificKeyByLength(constants.MeasTagRecommendHierarchyType, compTag)
|
||||||
|
members, err := rdb.SMembers(ctx, queryKey).Result()
|
||||||
|
if err != nil && err != redis.Nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
recommends := combineQueryResultByInput(constants.MeasTagRecommendHierarchyType, recommendLenType, inputSlice, members)
|
||||||
|
recommends = confirmMeasRecommendResultsByHash(ctx, rdb, inputSlice, members, recommends)
|
||||||
|
if len(recommends) == 0 {
|
||||||
|
return []string{}, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return recommends, recommendPrefixOffset(inputSlice[:len(inputSlice)-1]), nil
|
||||||
|
}
|
||||||
|
|
||||||
func filterMembersByTrimmedPrefix(members []string, searchInput string) ([]string, string) {
|
func filterMembersByTrimmedPrefix(members []string, searchInput string) ([]string, string) {
|
||||||
for len([]rune(searchInput)) != 0 {
|
for len([]rune(searchInput)) != 0 {
|
||||||
filtered := make([]string, 0, len(members))
|
filtered := make([]string, 0, len(members))
|
||||||
|
|
@ -1060,7 +1100,7 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co
|
||||||
|
|
||||||
if keyExists {
|
if keyExists {
|
||||||
var QueryData []string
|
var QueryData []string
|
||||||
if hierarchy == constants.MaxIdentifyHierarchy || (hierarchy == constants.IdentifyHierarchy && redisSetKey == constants.RedisAllMeasTagSetKey) {
|
if hierarchy == constants.MeasTagRecommendHierarchyType {
|
||||||
QueryData = []string{""}
|
QueryData = []string{""}
|
||||||
} else {
|
} else {
|
||||||
QueryData = []string{"."}
|
QueryData = []string{"."}
|
||||||
|
|
@ -1148,6 +1188,10 @@ func runFuzzySearch(ctx context.Context, rdb *redis.Client, searchInput string,
|
||||||
return nil, 0, fmt.Errorf("redisearch suggest failed: %w", err)
|
return nil, 0, fmt.Errorf("redisearch suggest failed: %w", err)
|
||||||
}
|
}
|
||||||
if len(results) == 0 {
|
if len(results) == 0 {
|
||||||
|
if fuzzyExactContinuationExists(ctx, rdb, hierarchy, recommendLenType, memberComparePrefix, searchInput, fuzzyInput) {
|
||||||
|
return []string{"."}, fuzzyRecommendOffset(searchPrefix, searchInput), nil
|
||||||
|
}
|
||||||
|
|
||||||
// 如果没有结果,退一步(删除最后一个字符)并继续循环
|
// 如果没有结果,退一步(删除最后一个字符)并继续循环
|
||||||
// TODO 考虑使用其他方式代替 for 循环退一字符的查询方式
|
// TODO 考虑使用其他方式代替 for 循环退一字符的查询方式
|
||||||
searchInput = trimLastRune(searchInput)
|
searchInput = trimLastRune(searchInput)
|
||||||
|
|
@ -1187,7 +1231,7 @@ func runFuzzySearch(ctx context.Context, rdb *redis.Client, searchInput string,
|
||||||
}
|
}
|
||||||
|
|
||||||
if termHierarchyLen == compareHierarchyLen && termPrefix == comparePrefix && strings.HasPrefix(termLastPart, searchInput) {
|
if termHierarchyLen == compareHierarchyLen && termPrefix == comparePrefix && strings.HasPrefix(termLastPart, searchInput) {
|
||||||
exists, err := fuzzyRecommendMemberExists(ctx, rdb, hierarchy, memberComparePrefix, termLastPart)
|
exists, err := fuzzyRecommendMemberExists(ctx, rdb, hierarchy, recommendLenType, memberComparePrefix, termLastPart)
|
||||||
if err != nil || !exists {
|
if err != nil || !exists {
|
||||||
logger.Info(ctx, "fuzzy recommend term not found in specific redis set",
|
logger.Info(ctx, "fuzzy recommend term not found in specific redis set",
|
||||||
"hierarchy", hierarchy,
|
"hierarchy", hierarchy,
|
||||||
|
|
@ -1201,6 +1245,11 @@ func runFuzzySearch(ctx context.Context, rdb *redis.Client, searchInput string,
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if termLastPart == searchInput {
|
||||||
|
recommends = append(recommends, fuzzyExactContinuationValue(hierarchy))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
recommend := result.Term
|
recommend := result.Term
|
||||||
if hierarchy == constants.MeasTagRecommendHierarchyType && configToken != "" && termPrefix == memberComparePrefix {
|
if hierarchy == constants.MeasTagRecommendHierarchyType && configToken != "" && termPrefix == memberComparePrefix {
|
||||||
recommend = strings.Join([]string{termPrefix, configToken, termLastPart}, ".")
|
recommend = strings.Join([]string{termPrefix, configToken, termLastPart}, ".")
|
||||||
|
|
@ -1209,16 +1258,42 @@ func runFuzzySearch(ctx context.Context, rdb *redis.Client, searchInput string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(recommends) == 0 {
|
if len(recommends) == 0 {
|
||||||
|
if fuzzyExactContinuationExists(ctx, rdb, hierarchy, recommendLenType, memberComparePrefix, searchInput, fuzzyInput) {
|
||||||
|
return []string{fuzzyExactContinuationValue(hierarchy)}, fuzzyRecommendOffset(searchPrefix, searchInput), nil
|
||||||
|
}
|
||||||
|
|
||||||
searchInput = trimLastRune(searchInput)
|
searchInput = trimLastRune(searchInput)
|
||||||
searchInputLen = len([]rune(searchInput))
|
searchInputLen = len([]rune(searchInput))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return recommends, fuzzyRecommendOffset(searchPrefix, searchInput), nil
|
offset := fuzzyRecommendOffset(searchPrefix, searchInput)
|
||||||
|
return recommends, offset, nil
|
||||||
}
|
}
|
||||||
return []string{}, 0, nil
|
return []string{}, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fuzzyExactContinuationExists(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, memberComparePrefix string, searchInput string, fuzzyInput string) bool {
|
||||||
|
exists, err := fuzzyRecommendMemberExists(ctx, rdb, hierarchy, recommendLenType, memberComparePrefix, searchInput)
|
||||||
|
if err != nil {
|
||||||
|
logger.Info(ctx, "fuzzy exact continuation check failed",
|
||||||
|
"hierarchy", hierarchy,
|
||||||
|
"recommend_len_type", recommendLenType,
|
||||||
|
"query_key", fuzzyInput,
|
||||||
|
"search_input", searchInput,
|
||||||
|
"error", err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
func fuzzyExactContinuationValue(hierarchy constants.RecommendHierarchyType) string {
|
||||||
|
if hierarchy == constants.MeasTagRecommendHierarchyType {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return "."
|
||||||
|
}
|
||||||
|
|
||||||
// fuzzyRecommendOffset 返回模糊命中的裁剪位置, 保留完整输入前缀参与 offset。
|
// fuzzyRecommendOffset 返回模糊命中的裁剪位置, 保留完整输入前缀参与 offset。
|
||||||
func fuzzyRecommendOffset(searchPrefix string, searchInput string) int {
|
func fuzzyRecommendOffset(searchPrefix string, searchInput string) int {
|
||||||
if searchPrefix == "" {
|
if searchPrefix == "" {
|
||||||
|
|
@ -1228,8 +1303,8 @@ func fuzzyRecommendOffset(searchPrefix string, searchInput string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fuzzyRecommendMemberExists 校验模糊候选末级 token 是否存在于对应 Redis set。
|
// fuzzyRecommendMemberExists 校验模糊候选末级 token 是否存在于对应 Redis set。
|
||||||
func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, comparePrefix string, termLastPart string) (bool, error) {
|
func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, comparePrefix string, termLastPart string) (bool, error) {
|
||||||
setKey, ok := fuzzyRecommendMemberSetKey(hierarchy, comparePrefix)
|
setKey, ok := fuzzyRecommendMemberSetKey(hierarchy, recommendLenType, comparePrefix)
|
||||||
if !ok {
|
if !ok {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
@ -1237,7 +1312,7 @@ func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarch
|
||||||
}
|
}
|
||||||
|
|
||||||
// fuzzyRecommendMemberSetKey 返回模糊候选校验时应使用的 Redis set key。
|
// fuzzyRecommendMemberSetKey 返回模糊候选校验时应使用的 Redis set key。
|
||||||
func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, comparePrefix string) (string, bool) {
|
func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, recommendLenType string, comparePrefix string) (string, bool) {
|
||||||
switch hierarchy {
|
switch hierarchy {
|
||||||
case constants.GridRecommendHierarchyType:
|
case constants.GridRecommendHierarchyType:
|
||||||
return constants.RedisAllGridSetKey, true
|
return constants.RedisAllGridSetKey, true
|
||||||
|
|
@ -1246,6 +1321,9 @@ func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, comp
|
||||||
case constants.StationRecommendHierarchyType:
|
case constants.StationRecommendHierarchyType:
|
||||||
return fmt.Sprintf(constants.RedisSpecZoneStationSetKey, lastRecommendPrefixToken(comparePrefix)), comparePrefix != ""
|
return fmt.Sprintf(constants.RedisSpecZoneStationSetKey, lastRecommendPrefixToken(comparePrefix)), comparePrefix != ""
|
||||||
case constants.CompNSPathRecommendHierarchyType:
|
case constants.CompNSPathRecommendHierarchyType:
|
||||||
|
if recommendLenType == constants.IsLocalRecommendLength {
|
||||||
|
return constants.RedisAllCompNSPathSetKey, true
|
||||||
|
}
|
||||||
return fmt.Sprintf(constants.RedisSpecStationCompNSPATHSetKey, lastRecommendPrefixToken(comparePrefix)), comparePrefix != ""
|
return fmt.Sprintf(constants.RedisSpecStationCompNSPATHSetKey, lastRecommendPrefixToken(comparePrefix)), comparePrefix != ""
|
||||||
case constants.CompTagRecommendHierarchyType:
|
case constants.CompTagRecommendHierarchyType:
|
||||||
return fmt.Sprintf(constants.RedisSpecCompNSPathCompTagSetKey, lastRecommendPrefixToken(comparePrefix)), comparePrefix != ""
|
return fmt.Sprintf(constants.RedisSpecCompNSPathCompTagSetKey, lastRecommendPrefixToken(comparePrefix)), comparePrefix != ""
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,78 @@ func TestFuzzyRecommendOffsetUsesFullMatchedInput(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFuzzyRecommendMemberSetKeyUsesLocalNSPathSet(t *testing.T) {
|
||||||
|
setKey, ok := fuzzyRecommendMemberSetKey(constants.CompNSPathRecommendHierarchyType, constants.IsLocalRecommendLength, "")
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected local nspath fuzzy member check to use a redis set")
|
||||||
|
}
|
||||||
|
if setKey != constants.RedisAllCompNSPathSetKey {
|
||||||
|
t.Fatalf("expected set key %q, got %q", constants.RedisAllCompNSPathSetKey, setKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNormalizeRecommendResultsKeepsFuzzyExactContinuation(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
recommendType constants.RecommendHierarchyType
|
||||||
|
offset int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "local nspath typo completes current level",
|
||||||
|
input: "110kV_TV-demoProjectx",
|
||||||
|
recommendType: constants.CompNSPathRecommendHierarchyType,
|
||||||
|
offset: len([]rune("110kV_TV-demoProject")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "grid typo completes current level",
|
||||||
|
input: "grid000x",
|
||||||
|
recommendType: constants.GridRecommendHierarchyType,
|
||||||
|
offset: len([]rune("grid000")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zone typo completes current level",
|
||||||
|
input: "grid000.zone000x",
|
||||||
|
recommendType: constants.ZoneRecommendHierarchyType,
|
||||||
|
offset: len([]rune("grid000.zone000")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "station typo completes current level",
|
||||||
|
input: "grid000.zone000.station000x",
|
||||||
|
recommendType: constants.StationRecommendHierarchyType,
|
||||||
|
offset: len([]rune("grid000.zone000.station000")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "full nspath typo completes current level",
|
||||||
|
input: "grid000.zone000.station000.110kV_TV-demoProjectx",
|
||||||
|
recommendType: constants.CompNSPathRecommendHierarchyType,
|
||||||
|
offset: len([]rune("grid000.zone000.station000.110kV_TV-demoProject")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
results := map[string]SearchResult{
|
||||||
|
tt.recommendType.String(): {
|
||||||
|
RecommendType: tt.recommendType,
|
||||||
|
QueryDatas: []string{"."},
|
||||||
|
IsFuzzy: true,
|
||||||
|
Offset: tt.offset,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := normalizeRecommendResults(tt.input, results)
|
||||||
|
result := got[tt.recommendType.String()]
|
||||||
|
if result.Offset != tt.offset {
|
||||||
|
t.Fatalf("expected offset %d, got %d", tt.offset, result.Offset)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result.QueryDatas, []string{"."}) {
|
||||||
|
t.Fatalf("expected fuzzy exact continuation '.', got %#v", result.QueryDatas)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNormalizeRecommendResultsUsesInputLengthForExactCompletion(t *testing.T) {
|
func TestNormalizeRecommendResultsUsesInputLengthForExactCompletion(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -350,6 +422,78 @@ func TestNormalizeRecommendResultsKeepsFullAndLocalBayMeasurementSuffixesConsist
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNormalizeRecommendResultsKeepsConfigMismatchFallbackConsistentWithEmptyInput(t *testing.T) {
|
||||||
|
prefix := "110kV_TV-demoProject.cable_22-testProject1110kV_TV"
|
||||||
|
members := []string{"bay", "base_extend", "model", "component"}
|
||||||
|
groupResults := combineQueryResultByInput(constants.ConfigRecommendHierarchyType, constants.IsLocalRecommendLength, strings.Split(prefix+".", "."), members)
|
||||||
|
offset := recommendPrefixOffset(strings.Split(prefix, "."))
|
||||||
|
|
||||||
|
emptyInputResults := map[string]SearchResult{
|
||||||
|
constants.ConfigRecommendHierarchyType.String(): {
|
||||||
|
RecommendType: constants.ConfigRecommendHierarchyType,
|
||||||
|
QueryDatas: append([]string{}, groupResults...),
|
||||||
|
IsFuzzy: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mismatchFallbackResults := map[string]SearchResult{
|
||||||
|
constants.ConfigRecommendHierarchyType.String(): {
|
||||||
|
RecommendType: constants.ConfigRecommendHierarchyType,
|
||||||
|
QueryDatas: append([]string{}, groupResults...),
|
||||||
|
IsFuzzy: true,
|
||||||
|
IsFallback: true,
|
||||||
|
Offset: offset,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyGot := normalizeRecommendResults(prefix+".", emptyInputResults)
|
||||||
|
mismatchGot := normalizeRecommendResults(prefix+".x", mismatchFallbackResults)
|
||||||
|
emptyResult := emptyGot[constants.ConfigRecommendHierarchyType.String()]
|
||||||
|
mismatchResult := mismatchGot[constants.ConfigRecommendHierarchyType.String()]
|
||||||
|
|
||||||
|
if mismatchResult.Offset != emptyResult.Offset {
|
||||||
|
t.Fatalf("expected config mismatch fallback offset %d, got %d", emptyResult.Offset, mismatchResult.Offset)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(mismatchResult.QueryDatas, emptyResult.QueryDatas) {
|
||||||
|
t.Fatalf("expected config mismatch fallback recommends to match empty input, empty=%#v mismatch=%#v", emptyResult.QueryDatas, mismatchResult.QueryDatas)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNormalizeRecommendResultsKeepsMeasurementMismatchFallbackConsistentWithEmptyInput(t *testing.T) {
|
||||||
|
prefix := "grid000.zone000.station000.110kV_TV-demoProject.cable_22-testProject1110kV_TV.bay"
|
||||||
|
members := []string{"IA_rms_CTA-testProject1", "IB_rms_CTA-testProject1", "IC_rms_CTA-testProject1"}
|
||||||
|
groupResults := combineQueryResultByInput(constants.MeasTagRecommendHierarchyType, constants.FullRecommendLength, strings.Split(prefix+".", "."), members)
|
||||||
|
offset := recommendPrefixOffset(strings.Split(prefix, "."))
|
||||||
|
|
||||||
|
emptyInputResults := map[string]SearchResult{
|
||||||
|
constants.MeasTagRecommendHierarchyType.String(): {
|
||||||
|
RecommendType: constants.MeasTagRecommendHierarchyType,
|
||||||
|
QueryDatas: append([]string{}, groupResults...),
|
||||||
|
IsFuzzy: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mismatchFallbackResults := map[string]SearchResult{
|
||||||
|
constants.MeasTagRecommendHierarchyType.String(): {
|
||||||
|
RecommendType: constants.MeasTagRecommendHierarchyType,
|
||||||
|
QueryDatas: append([]string{}, groupResults...),
|
||||||
|
IsFuzzy: true,
|
||||||
|
IsFallback: true,
|
||||||
|
Offset: offset,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyGot := normalizeRecommendResults(prefix+".", emptyInputResults)
|
||||||
|
mismatchGot := normalizeRecommendResults(prefix+".x", mismatchFallbackResults)
|
||||||
|
emptyResult := emptyGot[constants.MeasTagRecommendHierarchyType.String()]
|
||||||
|
mismatchResult := mismatchGot[constants.MeasTagRecommendHierarchyType.String()]
|
||||||
|
|
||||||
|
if mismatchResult.Offset != emptyResult.Offset {
|
||||||
|
t.Fatalf("expected measurement mismatch fallback offset %d, got %d", emptyResult.Offset, mismatchResult.Offset)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(mismatchResult.QueryDatas, emptyResult.QueryDatas) {
|
||||||
|
t.Fatalf("expected measurement mismatch fallback recommends to match empty input, empty=%#v mismatch=%#v", emptyResult.QueryDatas, mismatchResult.QueryDatas)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRecommendGroupTokens(t *testing.T) {
|
func TestRecommendGroupTokens(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue