refactor: simplify redis recommendation concurrency
- replace fan-in channel recommendation searches with errgroup-based execution - return SearchResult directly from Redis recommendation helper functions - fallback leading-dot recommendation input to initial token suggestions - remove unused recommendLenType parameter from fuzzy member set validation - clean up small model selection and naming issues
This commit is contained in:
parent
f9824e2b24
commit
d8668afa46
|
|
@ -2,6 +2,8 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"modelRT/constants"
|
"modelRT/constants"
|
||||||
"modelRT/database"
|
"modelRT/database"
|
||||||
"modelRT/logger"
|
"modelRT/logger"
|
||||||
|
|
@ -152,6 +154,8 @@ func validateBatchImportParams(params map[string]any) bool {
|
||||||
func validateTestTaskParams(params map[string]any) bool {
|
func validateTestTaskParams(params map[string]any) bool {
|
||||||
// Test task has optional parameters, all are valid
|
// Test task has optional parameters, all are valid
|
||||||
// sleep_duration defaults to 60 seconds if not provided
|
// sleep_duration defaults to 60 seconds if not provided
|
||||||
|
// TODO Add more validation logic for test task parameters if needed
|
||||||
|
fmt.Println(params)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,6 @@ func (s *ShortAttrInfo) IsLocal() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAttrValue define return the attribute value
|
// GetAttrValue define return the attribute value
|
||||||
func (l *ShortAttrInfo) GetAttrValue() any {
|
func (s *ShortAttrInfo) GetAttrValue() any {
|
||||||
return l.AttrValue
|
return s.AttrValue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package model define model struct of model runtime service
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -7,11 +8,12 @@ import (
|
||||||
|
|
||||||
// SelectModelByType define select the data structure for parsing based on the input model type
|
// SelectModelByType define select the data structure for parsing based on the input model type
|
||||||
func SelectModelByType(modelType int) BasicModelInterface {
|
func SelectModelByType(modelType int) BasicModelInterface {
|
||||||
if modelType == constants.BusbarType {
|
switch modelType {
|
||||||
|
case constants.BusbarType:
|
||||||
return &orm.BusbarSection{}
|
return &orm.BusbarSection{}
|
||||||
} else if modelType == constants.AsyncMotorType {
|
case constants.AsyncMotorType:
|
||||||
return &orm.AsyncMotor{}
|
return &orm.AsyncMotor{}
|
||||||
} else if modelType == constants.DemoType {
|
case constants.DemoType:
|
||||||
return &orm.Demo{}
|
return &orm.Demo{}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"modelRT/constants"
|
"modelRT/constants"
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
|
|
@ -16,6 +17,7 @@ import (
|
||||||
"github.com/RediSearch/redisearch-go/v2/redisearch"
|
"github.com/RediSearch/redisearch-go/v2/redisearch"
|
||||||
redigo "github.com/gomodule/redigo/redis"
|
redigo "github.com/gomodule/redigo/redis"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SearchResult define struct to store redis query recommend search result
|
// SearchResult define struct to store redis query recommend search result
|
||||||
|
|
@ -36,12 +38,44 @@ func InitAutocompleterWithPool(pool *redigo.Pool) {
|
||||||
ac = redisearch.NewAutocompleterFromPool(pool, constants.RedisSearchDictName)
|
ac = redisearch.NewAutocompleterFromPool(pool, constants.RedisSearchDictName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type recommendSearchJob func() SearchResult
|
||||||
|
|
||||||
|
func runRecommendSearches(ctx context.Context, logMsg string, filterCompNSPath bool, jobs ...recommendSearchJob) map[string]SearchResult {
|
||||||
|
results := make(map[string]SearchResult)
|
||||||
|
var mu sync.Mutex
|
||||||
|
var group errgroup.Group
|
||||||
|
|
||||||
|
for _, job := range jobs {
|
||||||
|
job := job
|
||||||
|
group.Go(func() error {
|
||||||
|
result := job()
|
||||||
|
if result.Err != nil {
|
||||||
|
return fmt.Errorf("%s: %w", result.RecommendType, result.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if filterCompNSPath && result.RecommendType == constants.CompNSPathRecommendHierarchyType {
|
||||||
|
result.QueryDatas = filterLocalNSPathResults(result.QueryDatas)
|
||||||
|
}
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
|
results[result.RecommendType.String()] = result
|
||||||
|
mu.Unlock()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := group.Wait(); err != nil {
|
||||||
|
logger.Error(ctx, logMsg, "error", err)
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
// levelOneRedisSearch 处理第一段输入的搜索, 例如 grid 或本地 nspath。
|
// levelOneRedisSearch 处理第一段输入的搜索, 例如 grid 或本地 nspath。
|
||||||
func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, searchInput string, searchRedisKey string, fanInChan chan SearchResult) {
|
func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, searchInput string, searchRedisKey string) (result SearchResult) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
logger.Error(ctx, "searchFunc panicked", "panic", r)
|
logger.Error(ctx, "searchFunc panicked", "panic", r)
|
||||||
fanInChan <- SearchResult{
|
result = SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
|
|
@ -54,64 +88,59 @@ func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy const
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "redis membership check failed", "key", searchRedisKey, "member", searchInput, "op", "SIsMember", "error", err)
|
logger.Error(ctx, "redis membership check failed", "key", searchRedisKey, "member", searchInput, "op", "SIsMember", "error", err)
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the input key is the complete hierarchical value
|
// the input key is the complete hierarchical value
|
||||||
if exists {
|
if exists {
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: []string{"."},
|
QueryDatas: []string{"."},
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// process fuzzy search result
|
// process fuzzy search result
|
||||||
recommends, offset, err := runFuzzySearch(ctx, rdb, searchInput, "", hierarchy, recommendLenType)
|
recommends, offset, err := runFuzzySearch(ctx, rdb, searchInput, "", hierarchy, recommendLenType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, fmt.Sprintf("fuzzy search failed for %s hierarchical", util.GetLevelStrByRdsKey(searchRedisKey)), "search_input", searchInput, "error", err)
|
logger.Error(ctx, fmt.Sprintf("fuzzy search failed for %s hierarchical", util.GetLevelStrByRdsKey(searchRedisKey)), "search_input", searchInput, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(recommends) > 0 {
|
if len(recommends) > 0 {
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: recommends,
|
QueryDatas: recommends,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recommends, err = fallbackAllCurrentLevel(ctx, rdb, hierarchy)
|
recommends, err = fallbackAllCurrentLevel(ctx, rdb, hierarchy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "fallback all keys at current level failed", "hierarchy", hierarchy, "search_input", searchInput, "error", err)
|
logger.Error(ctx, "fallback all keys at current level failed", "hierarchy", hierarchy, "search_input", searchInput, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
IsFallback: true,
|
IsFallback: true,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: recommends,
|
QueryDatas: recommends,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
|
|
@ -124,165 +153,102 @@ func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy const
|
||||||
// RedisSearchRecommend define func of redis search by input string and return recommend results
|
// RedisSearchRecommend define func of redis search by input string and return recommend results
|
||||||
func RedisSearchRecommend(ctx context.Context, input string) map[string]SearchResult {
|
func RedisSearchRecommend(ctx context.Context, input string) map[string]SearchResult {
|
||||||
rdb := diagram.GetRedisClientInstance()
|
rdb := diagram.GetRedisClientInstance()
|
||||||
finalizeResults := func(results map[string]SearchResult) map[string]SearchResult {
|
finalizeResults := func(normalizeInput string, results map[string]SearchResult) map[string]SearchResult {
|
||||||
results = suppressFallbackResultsWhenConcreteHitExists(results)
|
results = suppressFallbackResultsWhenConcreteHitExists(results)
|
||||||
return normalizeRecommendResults(input, results)
|
return normalizeRecommendResults(normalizeInput, results)
|
||||||
}
|
}
|
||||||
|
|
||||||
if input == "" {
|
if input == "" || shouldFallbackToInitialRecommend(input) {
|
||||||
fanInChan := make(chan SearchResult, 2)
|
results := runRecommendSearches(ctx, "return all keys at the special level from redis failed", true,
|
||||||
// return all grid tagname
|
func() SearchResult {
|
||||||
go getAllKeyByGridLevel(ctx, rdb, fanInChan)
|
return getAllKeyByGridLevel(ctx, rdb)
|
||||||
// return all component nspath
|
},
|
||||||
go getAllKeyByNSPathLevel(ctx, rdb, fanInChan)
|
func() SearchResult {
|
||||||
results := make(map[string]SearchResult)
|
return getAllKeyByNSPathLevel(ctx, rdb)
|
||||||
for range 2 {
|
},
|
||||||
result := <-fanInChan
|
)
|
||||||
if result.Err != nil {
|
return finalizeResults("", results)
|
||||||
logger.Error(ctx, "return all keys at the special level from redis failed", "recommend_type", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecommendType == constants.CompNSPathRecommendHierarchyType {
|
|
||||||
result.QueryDatas = filterLocalNSPathResults(result.QueryDatas)
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inputSlice := strings.Split(input, ".")
|
inputSlice := strings.Split(input, ".")
|
||||||
inputSliceLen := len(inputSlice)
|
inputSliceLen := len(inputSlice)
|
||||||
|
|
||||||
fanInChan := make(chan SearchResult, 4)
|
|
||||||
switch inputSliceLen {
|
switch inputSliceLen {
|
||||||
case 1:
|
case 1:
|
||||||
searchInput := inputSlice[0]
|
searchInput := inputSlice[0]
|
||||||
// grid tagname search
|
results := runRecommendSearches(ctx, "exec redis fuzzy search by key failed", true,
|
||||||
go levelOneRedisSearch(ctx, rdb, constants.GridRecommendHierarchyType, constants.FullRecommendLength, searchInput, constants.RedisAllGridSetKey, fanInChan)
|
func() SearchResult {
|
||||||
// component nspath search
|
return levelOneRedisSearch(ctx, rdb, constants.GridRecommendHierarchyType, constants.FullRecommendLength, searchInput, constants.RedisAllGridSetKey)
|
||||||
go levelOneRedisSearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.IsLocalRecommendLength, searchInput, constants.RedisAllCompNSPathSetKey, fanInChan)
|
},
|
||||||
|
func() SearchResult {
|
||||||
results := make(map[string]SearchResult)
|
return levelOneRedisSearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.IsLocalRecommendLength, searchInput, constants.RedisAllCompNSPathSetKey)
|
||||||
// TODO 后续根据支持的数据标识语法长度,进行值的变更
|
},
|
||||||
for range 2 {
|
)
|
||||||
result := <-fanInChan
|
return finalizeResults(input, results)
|
||||||
if result.Err != nil {
|
|
||||||
logger.Error(ctx, "exec redis fuzzy search by key failed", "recommend_type", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecommendType == constants.CompNSPathRecommendHierarchyType {
|
|
||||||
result.QueryDatas = filterLocalNSPathResults(result.QueryDatas)
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
case 2:
|
case 2:
|
||||||
// zone tagname search
|
results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false,
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.ZoneRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllZoneSetKey, inputSlice, fanInChan)
|
func() SearchResult {
|
||||||
// component tagname search
|
return handleLevelFuzzySearch(ctx, rdb, constants.ZoneRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllZoneSetKey, inputSlice)
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllCompTagSetKey, inputSlice, fanInChan)
|
},
|
||||||
// measurement tagname search by token4-token7 shorthand
|
func() SearchResult {
|
||||||
go handleNSPathMeasSearch(ctx, rdb, inputSlice, fanInChan)
|
return handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllCompTagSetKey, inputSlice)
|
||||||
results := make(map[string]SearchResult)
|
},
|
||||||
for range 3 {
|
func() SearchResult {
|
||||||
result := <-fanInChan
|
return handleNSPathMeasSearch(ctx, rdb, inputSlice)
|
||||||
if result.Err != nil {
|
},
|
||||||
logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err)
|
)
|
||||||
continue
|
return finalizeResults(input, results)
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
case 3:
|
case 3:
|
||||||
// station tanname search
|
results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false,
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.StationRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllStationSetKey, inputSlice, fanInChan)
|
func() SearchResult {
|
||||||
// config search
|
return handleLevelFuzzySearch(ctx, rdb, constants.StationRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllStationSetKey, inputSlice)
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice, fanInChan)
|
},
|
||||||
|
func() SearchResult {
|
||||||
results := make(map[string]SearchResult)
|
return handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice)
|
||||||
for range 2 {
|
},
|
||||||
result := <-fanInChan
|
)
|
||||||
if result.Err != nil {
|
return finalizeResults(input, results)
|
||||||
logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
case 4:
|
case 4:
|
||||||
// component nspath search
|
results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false,
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompNSPathSetKey, inputSlice, fanInChan)
|
func() SearchResult {
|
||||||
// measurement tagname search
|
return handleLevelFuzzySearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompNSPathSetKey, inputSlice)
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice, fanInChan)
|
},
|
||||||
|
func() SearchResult {
|
||||||
results := make(map[string]SearchResult)
|
return handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice)
|
||||||
for range 2 {
|
},
|
||||||
result := <-fanInChan
|
)
|
||||||
if result.Err != nil {
|
return finalizeResults(input, results)
|
||||||
logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
case 5:
|
case 5:
|
||||||
// component tagname search
|
results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false,
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompTagSetKey, inputSlice, fanInChan)
|
func() SearchResult {
|
||||||
|
return handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompTagSetKey, inputSlice)
|
||||||
results := make(map[string]SearchResult)
|
},
|
||||||
for range 1 {
|
)
|
||||||
result := <-fanInChan
|
return finalizeResults(input, results)
|
||||||
if result.Err != nil {
|
|
||||||
logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
case 6:
|
case 6:
|
||||||
// config search
|
results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false,
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllConfigSetKey, inputSlice, fanInChan)
|
func() SearchResult {
|
||||||
|
return handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllConfigSetKey, inputSlice)
|
||||||
results := make(map[string]SearchResult)
|
},
|
||||||
for range 1 {
|
)
|
||||||
result := <-fanInChan
|
return finalizeResults(input, results)
|
||||||
if result.Err != nil {
|
|
||||||
logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
case 7:
|
case 7:
|
||||||
// measurement tagname search
|
results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false,
|
||||||
go handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllMeasTagSetKey, inputSlice, fanInChan)
|
func() SearchResult {
|
||||||
|
return handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllMeasTagSetKey, inputSlice)
|
||||||
results := make(map[string]SearchResult)
|
},
|
||||||
for range 1 {
|
)
|
||||||
result := <-fanInChan
|
return finalizeResults(input, results)
|
||||||
if result.Err != nil {
|
|
||||||
logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results[result.RecommendType.String()] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalizeResults(results)
|
|
||||||
default:
|
default:
|
||||||
logger.Error(ctx, "unsupport length of search input", "input_len", inputSliceLen)
|
logger.Error(ctx, "unsupport length of search input", "input_len", inputSliceLen)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldFallbackToInitialRecommend(input string) bool {
|
||||||
|
return strings.HasPrefix(input, ".")
|
||||||
|
}
|
||||||
|
|
||||||
// suppressFallbackResultsWhenConcreteHitExists 有明确命中时丢弃兜底结果, 避免返回过宽推荐。
|
// suppressFallbackResultsWhenConcreteHitExists 有明确命中时丢弃兜底结果, 避免返回过宽推荐。
|
||||||
func suppressFallbackResultsWhenConcreteHitExists(results map[string]SearchResult) map[string]SearchResult {
|
func suppressFallbackResultsWhenConcreteHitExists(results map[string]SearchResult) map[string]SearchResult {
|
||||||
hasConcreteHit := false
|
hasConcreteHit := false
|
||||||
|
|
@ -494,23 +460,22 @@ func getAllSetKeyByHierarchy(hierarchy constants.RecommendHierarchyType) (string
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAllKeyByGridLevel 返回所有 grid tag, 用于空输入时的初始推荐。
|
// getAllKeyByGridLevel 返回所有 grid tag, 用于空输入时的初始推荐。
|
||||||
func getAllKeyByGridLevel(ctx context.Context, rdb *redis.Client, fanInChan chan SearchResult) {
|
func getAllKeyByGridLevel(ctx context.Context, rdb *redis.Client) SearchResult {
|
||||||
setKey := constants.RedisAllGridSetKey
|
setKey := constants.RedisAllGridSetKey
|
||||||
hierarchy := constants.GridRecommendHierarchyType
|
hierarchy := constants.GridRecommendHierarchyType
|
||||||
members, err := rdb.SMembers(ctx, setKey).Result()
|
members, err := rdb.SMembers(ctx, setKey).Result()
|
||||||
if err != nil && err != redigo.ErrNil {
|
if err != nil && err != redigo.ErrNil {
|
||||||
logger.Error(ctx, "get all members from redis by special key failed", "key", setKey, "op", "SMembers", "error", err)
|
logger.Error(ctx, "get all members from redis by special key failed", "key", setKey, "op", "SMembers", "error", err)
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: members,
|
QueryDatas: members,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
|
|
@ -519,23 +484,22 @@ func getAllKeyByGridLevel(ctx context.Context, rdb *redis.Client, fanInChan chan
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAllKeyByNSPathLevel 返回所有组件 nspath, 用于空输入时的初始推荐。
|
// getAllKeyByNSPathLevel 返回所有组件 nspath, 用于空输入时的初始推荐。
|
||||||
func getAllKeyByNSPathLevel(ctx context.Context, rdb *redis.Client, fanInChan chan SearchResult) {
|
func getAllKeyByNSPathLevel(ctx context.Context, rdb *redis.Client) SearchResult {
|
||||||
queryKey := constants.RedisAllCompNSPathSetKey
|
queryKey := constants.RedisAllCompNSPathSetKey
|
||||||
hierarchy := constants.CompNSPathRecommendHierarchyType
|
hierarchy := constants.CompNSPathRecommendHierarchyType
|
||||||
members, err := rdb.SMembers(ctx, queryKey).Result()
|
members, err := rdb.SMembers(ctx, queryKey).Result()
|
||||||
if err != nil && err != redigo.ErrNil {
|
if err != nil && err != redigo.ErrNil {
|
||||||
logger.Error(ctx, "get all members by special key failed", "key", queryKey, "op", "SMembers", "error", err)
|
logger.Error(ctx, "get all members by special key failed", "key", queryKey, "op", "SMembers", "error", err)
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: members,
|
QueryDatas: members,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
|
|
@ -611,7 +575,7 @@ func getSpecificKeyByLength(hierarchy constants.RecommendHierarchyType, keyPrefi
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleNSPathMeasSearch 处理 nspath.measurement 的简写搜索路径。
|
// handleNSPathMeasSearch 处理 nspath.measurement 的简写搜索路径。
|
||||||
func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice []string, fanInChan chan SearchResult) {
|
func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice []string) SearchResult {
|
||||||
hierarchy := constants.MeasTagRecommendHierarchyType
|
hierarchy := constants.MeasTagRecommendHierarchyType
|
||||||
nsPath := inputSlice[0]
|
nsPath := inputSlice[0]
|
||||||
searchInput := inputSlice[1]
|
searchInput := inputSlice[1]
|
||||||
|
|
@ -619,22 +583,20 @@ func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice [
|
||||||
nsPathExists, err := rdb.SIsMember(ctx, constants.RedisAllCompNSPathSetKey, nsPath).Result()
|
nsPathExists, err := rdb.SIsMember(ctx, constants.RedisAllCompNSPathSetKey, nsPath).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "check nspath exist from redis set failed", "key", constants.RedisAllCompNSPathSetKey, "nspath", nsPath, "error", err)
|
logger.Error(ctx, "check nspath exist from redis set failed", "key", constants.RedisAllCompNSPathSetKey, "nspath", nsPath, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if !nsPathExists {
|
if !nsPathExists {
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: []string{},
|
QueryDatas: []string{},
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
queryKey := fmt.Sprintf(constants.RedisSpecCompNSPathMeasSetKey, nsPath)
|
queryKey := fmt.Sprintf(constants.RedisSpecCompNSPathMeasSetKey, nsPath)
|
||||||
|
|
@ -642,57 +604,52 @@ func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice [
|
||||||
members, err := rdb.SMembers(ctx, queryKey).Result()
|
members, err := rdb.SMembers(ctx, queryKey).Result()
|
||||||
if err != nil && err != redis.Nil {
|
if err != nil && err != redis.Nil {
|
||||||
logger.Error(ctx, "query measurement tags by nspath failed", "key", queryKey, "nspath", nsPath, "error", err)
|
logger.Error(ctx, "query measurement tags by nspath failed", "key", queryKey, "nspath", nsPath, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: combineNSPathMeasResults(nsPath, members),
|
QueryDatas: combineNSPathMeasResults(nsPath, members),
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
measTagExists, err := rdb.SIsMember(ctx, queryKey, searchInput).Result()
|
measTagExists, err := rdb.SIsMember(ctx, queryKey, searchInput).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "check measurement tag exist from nspath set failed", "key", queryKey, "meas_tag", searchInput, "error", err)
|
logger.Error(ctx, "check measurement tag exist from nspath set failed", "key", queryKey, "meas_tag", searchInput, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if measTagExists {
|
if measTagExists {
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: []string{""},
|
QueryDatas: []string{""},
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recommends, offset, err := runNSPathMeasFuzzySearch(ctx, nsPath, searchInput)
|
recommends, offset, err := runNSPathMeasFuzzySearch(ctx, nsPath, searchInput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: recommends,
|
QueryDatas: recommends,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
|
|
@ -760,7 +717,7 @@ func splitLastToken(term string) (string, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleLevelFuzzySearch 处理第二层及以后层级的精确、模糊和兜底推荐。
|
// handleLevelFuzzySearch 处理第二层及以后层级的精确、模糊和兜底推荐。
|
||||||
func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, redisSetKey string, inputSlice []string, fanInChan chan SearchResult) {
|
func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, redisSetKey string, inputSlice []string) SearchResult {
|
||||||
inputSliceLen := len(inputSlice)
|
inputSliceLen := len(inputSlice)
|
||||||
searchInputIndex := inputSliceLen - 1
|
searchInputIndex := inputSliceLen - 1
|
||||||
searchInput := inputSlice[searchInputIndex]
|
searchInput := inputSlice[searchInputIndex]
|
||||||
|
|
@ -783,36 +740,33 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co
|
||||||
keyExists, err := rdb.SIsMember(ctx, redisSetKey, specificalKey).Result()
|
keyExists, err := rdb.SIsMember(ctx, redisSetKey, specificalKey).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "check key exist from redis set failed ", "key", redisSetKey, "error", err)
|
logger.Error(ctx, "check key exist from redis set failed ", "key", redisSetKey, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !keyExists {
|
if !keyExists {
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: []string{},
|
QueryDatas: []string{},
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
members, err := queryMemberFromSpecificsLevel(ctx, rdb, hierarchy, specificalKey)
|
members, err := queryMemberFromSpecificsLevel(ctx, rdb, hierarchy, specificalKey)
|
||||||
if err != nil && err != redis.Nil {
|
if err != nil && err != redis.Nil {
|
||||||
logger.Error(ctx, "query members from redis by special key failed", "key", specificalKey, "member", searchInput, "op", "SMember", "error", err)
|
logger.Error(ctx, "query members from redis by special key failed", "key", specificalKey, "member", searchInput, "op", "SMember", "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recommandResults := combineQueryResultByInput(hierarchy, recommendLenType, inputSlice, members)
|
recommandResults := combineQueryResultByInput(hierarchy, recommendLenType, inputSlice, members)
|
||||||
|
|
@ -838,25 +792,23 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co
|
||||||
}
|
}
|
||||||
recommandResults = secondConfirmResults
|
recommandResults = secondConfirmResults
|
||||||
}
|
}
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: recommandResults,
|
QueryDatas: recommandResults,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
keyExists, err := rdb.SIsMember(ctx, redisSetKey, searchInput).Result()
|
keyExists, err := rdb.SIsMember(ctx, redisSetKey, searchInput).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "check key exist from redis set failed ", "key", redisSetKey, "error", err)
|
logger.Error(ctx, "check key exist from redis set failed ", "key", redisSetKey, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if keyExists {
|
if keyExists {
|
||||||
|
|
@ -867,26 +819,24 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co
|
||||||
QueryData = []string{"."}
|
QueryData = []string{"."}
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: QueryData,
|
QueryDatas: QueryData,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start redis fuzzy search
|
// start redis fuzzy search
|
||||||
recommends, offset, err := runFuzzySearch(ctx, rdb, searchInput, searchPrefix, hierarchy, recommendLenType)
|
recommends, offset, err := runFuzzySearch(ctx, rdb, searchInput, searchPrefix, hierarchy, recommendLenType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "fuzzy search failed by hierarchy", "hierarchy", hierarchy, "search_input", searchInput, "error", err)
|
logger.Error(ctx, "fuzzy search failed by hierarchy", "hierarchy", hierarchy, "search_input", searchInput, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: false,
|
IsFuzzy: false,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isFallback := false
|
isFallback := false
|
||||||
|
|
@ -895,20 +845,19 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co
|
||||||
recommends, err = fallbackCurrentLevelByInput(ctx, rdb, hierarchy, inputSlice)
|
recommends, err = fallbackCurrentLevelByInput(ctx, rdb, hierarchy, inputSlice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "fallback all keys at current level failed", "hierarchy", hierarchy, "search_input", searchInput, "error", err)
|
logger.Error(ctx, "fallback all keys at current level failed", "hierarchy", hierarchy, "search_input", searchInput, "error", err)
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: nil,
|
QueryDatas: nil,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
IsFallback: true,
|
IsFallback: true,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
isFallback = true
|
isFallback = true
|
||||||
offset = 0
|
offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fanInChan <- SearchResult{
|
return SearchResult{
|
||||||
RecommendType: hierarchy,
|
RecommendType: hierarchy,
|
||||||
QueryDatas: recommends,
|
QueryDatas: recommends,
|
||||||
IsFuzzy: true,
|
IsFuzzy: true,
|
||||||
|
|
@ -992,7 +941,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, recommendLenType, comparePrefix, termLastPart)
|
exists, err := fuzzyRecommendMemberExists(ctx, rdb, hierarchy, comparePrefix, 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,
|
||||||
|
|
@ -1034,8 +983,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, recommendLenType string, comparePrefix string, termLastPart string) (bool, error) {
|
func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, comparePrefix string, termLastPart string) (bool, error) {
|
||||||
setKey, ok := fuzzyRecommendMemberSetKey(hierarchy, recommendLenType, comparePrefix)
|
setKey, ok := fuzzyRecommendMemberSetKey(hierarchy, comparePrefix)
|
||||||
if !ok {
|
if !ok {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
@ -1043,7 +992,7 @@ func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarch
|
||||||
}
|
}
|
||||||
|
|
||||||
// fuzzyRecommendMemberSetKey 返回模糊候选校验时应使用的 Redis set key。
|
// fuzzyRecommendMemberSetKey 返回模糊候选校验时应使用的 Redis set key。
|
||||||
func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, recommendLenType string, comparePrefix string) (string, bool) {
|
func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, comparePrefix string) (string, bool) {
|
||||||
switch hierarchy {
|
switch hierarchy {
|
||||||
case constants.GridRecommendHierarchyType:
|
case constants.GridRecommendHierarchyType:
|
||||||
return constants.RedisAllGridSetKey, true
|
return constants.RedisAllGridSetKey, true
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenNanoTsStr define func to generate nanosecond timestamp string by current time
|
// GenNanoTSStr define func to generate nanosecond timestamp string by current time
|
||||||
func GenNanoTsStr() string {
|
func GenNanoTSStr() string {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
nanoseconds := now.UnixNano()
|
nanoseconds := now.UnixNano()
|
||||||
timestampStr := strconv.FormatInt(nanoseconds, 10)
|
timestampStr := strconv.FormatInt(nanoseconds, 10)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue