diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go index de3c03ebb..cbe04609b 100644 --- a/internal/repo/search_common/search_repo.go +++ b/internal/repo/search_common/search_repo.go @@ -98,7 +98,7 @@ func NewSearchRepo( } // SearchContents search question and answer data -func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) { +func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs [][]string, userID string, votes int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) { words = filterWords(words) var ( @@ -160,8 +160,12 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs ast + ".tag_id": tagID, ast + ".status": entity.TagRelStatusAvailable, }) - argsQ = append(argsQ, entity.TagRelStatusAvailable, tagID) - argsA = append(argsA, entity.TagRelStatusAvailable, tagID) + argsQ = append(argsQ, entity.TagRelStatusAvailable) + argsA = append(argsA, entity.TagRelStatusAvailable) + for _, t := range tagID { + argsQ = append(argsQ, t) + argsA = append(argsA, t) + } } // check user @@ -236,7 +240,7 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs } // SearchQuestions search question data -func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) { +func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagIDs [][]string, notAccepted bool, views, answers int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) { words = filterWords(words) var ( qfs = qFields @@ -343,7 +347,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID } // SearchAnswers search answer data -func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) { +func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs [][]string, accepted bool, questionID string, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) { words = filterWords(words) var ( diff --git a/internal/schema/search_schema.go b/internal/schema/search_schema.go index e15339533..90b08cebe 100644 --- a/internal/schema/search_schema.go +++ b/internal/schema/search_schema.go @@ -64,7 +64,7 @@ type SearchCondition struct { // only show this question's answer QuestionID string // search query tags - Tags []string + Tags [][]string // search query keywords Words []string } diff --git a/internal/service/search_common/search.go b/internal/service/search_common/search.go index d1aea5479..c19fdc494 100644 --- a/internal/service/search_common/search.go +++ b/internal/service/search_common/search.go @@ -26,8 +26,8 @@ import ( ) type SearchRepo interface { - SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) - SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) - SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) + SearchContents(ctx context.Context, words []string, tagIDs [][]string, userID string, votes, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) + SearchQuestions(ctx context.Context, words []string, tagIDs [][]string, notAccepted bool, views, answers int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) + SearchAnswers(ctx context.Context, words []string, tagIDs [][]string, accepted bool, questionID string, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []*schema.SearchResult, err error) } diff --git a/internal/service/search_parser/search_parser.go b/internal/service/search_parser/search_parser.go index a5dfd6700..6485e1629 100644 --- a/internal/service/search_parser/search_parser.go +++ b/internal/service/search_parser/search_parser.go @@ -105,7 +105,7 @@ func (sp *SearchParser) ParseStructure(ctx context.Context, dto *schema.SearchDT } // parseTags parse search tags, return tag ids array -func (sp *SearchParser) parseTags(ctx context.Context, query *string) (tags []string) { +func (sp *SearchParser) parseTags(ctx context.Context, query *string) (tags [][]string) { var ( // expire tag pattern exprTag = `\[(.*?)\]` @@ -119,17 +119,25 @@ func (sp *SearchParser) parseTags(ctx context.Context, query *string) (tags []st return } - tags = []string{} + tags = make([][]string, 0) for _, item := range res { + tagGroup := make([]string, 0) tag, exists, err := sp.tagCommonService.GetTagBySlugName(ctx, item[1]) if err != nil || !exists { continue } + tagGroup = append(tagGroup, tag.ID) if tag.MainTagID > 0 { - tags = append(tags, fmt.Sprintf("%d", tag.MainTagID)) - } else { - tags = append(tags, tag.ID) + tagGroup = append(tagGroup, fmt.Sprintf("%d", tag.MainTagID)) } + synIDs, err := sp.tagCommonService.GetTagIDsByMainTagID(ctx, tag.ID) + if err != nil || !exists { + continue + } + tagGroup = append(tagGroup, tag.ID) + tagGroup = append(tagGroup, synIDs...) + tagGroup = converter.UniqueArray(tagGroup) + tags = append(tags, tagGroup) } // limit maximum 5 tags diff --git a/pkg/converter/array.go b/pkg/converter/array.go index 7718ee69b..2b122203e 100644 --- a/pkg/converter/array.go +++ b/pkg/converter/array.go @@ -32,3 +32,15 @@ func ArrayNotInArray(original []string, search []string) []string { } return result } + +func UniqueArray[T comparable](input []T) []T { + result := make([]T, 0, len(input)) + seen := make(map[T]bool, len(input)) + for _, element := range input { + if !seen[element] { + result = append(result, element) + seen[element] = true + } + } + return result +} diff --git a/plugin/search.go b/plugin/search.go index 20ff0f0ac..719d4294c 100644 --- a/plugin/search.go +++ b/plugin/search.go @@ -56,7 +56,7 @@ type SearchBasicCond struct { // The keywords for search. Words []string // TagIDs is a list of tag IDs. - TagIDs []string + TagIDs [][]string // The object's owner user ID. UserID string // The order of the search result.