feat(search): add description for search

This commit is contained in:
LinkinStars 2023-08-09 10:56:22 +08:00
parent eef4b9df9e
commit 8aa58bc182
7 changed files with 47 additions and 40 deletions

View File

@ -8054,7 +8054,7 @@ const docTemplate = `{
"description": "search response",
"type": "array",
"items": {
"$ref": "#/definitions/schema.SearchResp"
"$ref": "#/definitions/schema.SearchResults"
}
}
}
@ -8107,7 +8107,7 @@ const docTemplate = `{
}
}
},
"schema.SearchResp": {
"schema.SearchResults": {
"type": "object",
"properties": {
"object": {

View File

@ -39,7 +39,7 @@ func NewSearchController(
// @Security ApiKeyAuth
// @Param q query string true "query string"
// @Param order query string true "order" Enums(newest,active,score,relevance)
// @Success 200 {object} handler.RespBody{data=schema.SearchListResp}
// @Success 200 {object} handler.RespBody{data=schema.SearchResp}
// @Router /answer/api/v1/search [get]
func (sc *SearchController) Search(ctx *gin.Context) {
dto := schema.SearchDTO{}
@ -65,12 +65,9 @@ func (sc *SearchController) Search(ctx *gin.Context) {
}
}
resp, total, err := sc.searchService.Search(ctx, &dto)
if !isAdmin {
sc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionSearch, unit)
}
handler.HandleResponse(ctx, err, schema.SearchListResp{
Total: total,
SearchResp: resp,
})
resp, err := sc.searchService.Search(ctx, &dto)
handler.HandleResponse(ctx, err, resp)
}

View File

@ -70,7 +70,7 @@ func NewSearchRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo, userCommon
}
// 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.SearchResp, 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 (
@ -210,7 +210,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.SearchResp, 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
@ -319,7 +319,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.SearchResp, 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 (
@ -428,7 +428,7 @@ func (sr *searchRepo) parseOrder(ctx context.Context, order string) (res string)
}
// ParseSearchPluginResult parse search plugin result
func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResp, err error) {
func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResult, err error) {
var (
qres []map[string][]byte
res = make([]map[string][]byte, 0)
@ -455,7 +455,7 @@ func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin
}
// parseResult parse search result, return the data structure
func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) (resp []schema.SearchResp, err error) {
func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) (resp []schema.SearchResult, err error) {
for _, r := range res {
var (
objectKey,
@ -525,7 +525,7 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte)
AnswerCount: converter.StringToInt(string(r["answer_count"])),
StatusStr: status,
}
resp = append(resp, schema.SearchResp{
resp = append(resp, schema.SearchResult{
ObjectType: objectKey,
Object: object,
})

View File

@ -107,17 +107,17 @@ type TagResp struct {
Reserved bool `json:"reserved"`
}
type SearchResp struct {
type SearchResult struct {
// object_type
ObjectType string `json:"object_type"`
// this object
Object SearchObject `json:"object"`
}
type SearchListResp struct {
type SearchResp struct {
Total int64 `json:"count"`
// search response
SearchResp []SearchResp `json:"list"`
// extra fields
Extra interface{} `json:"extra"`
SearchResults []SearchResult `json:"list"`
// search plugin desc
SearchPluginIcon string `json:"search_icon,omitempty"`
}

View File

@ -7,8 +7,8 @@ import (
)
type SearchRepo interface {
SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes, page, size int, order string) (resp []schema.SearchResp, total int64, err error)
SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResp, total int64, err error)
SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResp, total int64, err error)
ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResp, 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)
}

View File

@ -24,7 +24,7 @@ func NewSearchService(
}
// Search search contents
func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (resp []schema.SearchResp, total int64, err error) {
func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (resp *schema.SearchResp, err error) {
if dto.Page < 1 {
dto.Page = 1
}
@ -33,39 +33,43 @@ func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (res
cond := ss.searchParser.ParseStructure(ctx, dto)
// check search plugin
var s plugin.Search
var finder plugin.Search
_ = plugin.CallSearch(func(search plugin.Search) error {
s = search
finder = search
return nil
})
resp = &schema.SearchResp{}
// search plugin is not found, call system search
if s == nil {
if finder == nil {
if cond.SearchAll() {
resp, total, err = ss.searchRepo.SearchContents(ctx, cond.Words, cond.Tags, cond.UserID, cond.VoteAmount, dto.Page, dto.Size, dto.Order)
resp.SearchResults, resp.Total, err =
ss.searchRepo.SearchContents(ctx, cond.Words, cond.Tags, cond.UserID, cond.VoteAmount, dto.Page, dto.Size, dto.Order)
} else if cond.SearchQuestion() {
resp, total, err = ss.searchRepo.SearchQuestions(ctx, cond.Words, cond.Tags, cond.NotAccepted, cond.Views, cond.AnswerAmount, dto.Page, dto.Size, dto.Order)
resp.SearchResults, resp.Total, err =
ss.searchRepo.SearchQuestions(ctx, cond.Words, cond.Tags, cond.NotAccepted, cond.Views, cond.AnswerAmount, dto.Page, dto.Size, dto.Order)
} else if cond.SearchAnswer() {
resp, total, err = ss.searchRepo.SearchAnswers(ctx, cond.Words, cond.Tags, cond.Accepted, cond.QuestionID, dto.Page, dto.Size, dto.Order)
resp.SearchResults, resp.Total, err =
ss.searchRepo.SearchAnswers(ctx, cond.Words, cond.Tags, cond.Accepted, cond.QuestionID, dto.Page, dto.Size, dto.Order)
}
return
}
return ss.searchByPlugin(ctx, s, cond, dto)
return ss.searchByPlugin(ctx, finder, cond, dto)
}
func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Search, cond *schema.SearchCondition, dto *schema.SearchDTO) (resp []schema.SearchResp, total int64, err error) {
func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Search, cond *schema.SearchCondition, dto *schema.SearchDTO) (resp *schema.SearchResp, err error) {
var res []plugin.SearchResult
resp = &schema.SearchResp{
SearchPluginIcon: finder.Description().Icon,
}
if cond.SearchAll() {
res, total, err = finder.SearchContents(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
res, resp.Total, err = finder.SearchContents(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
} else if cond.SearchQuestion() {
res, total, err = finder.SearchQuestions(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
res, resp.Total, err = finder.SearchQuestions(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
} else if cond.SearchAnswer() {
res, total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
res, resp.Total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order))
}
resp, err = ss.searchRepo.ParseSearchPluginResult(ctx, res)
if err != nil {
return nil, 0, err
}
return
resp.SearchResults, err = ss.searchRepo.ParseSearchPluginResult(ctx, res)
return resp, err
}

View File

@ -83,6 +83,7 @@ const (
type Search interface {
Base
Description() SearchDesc
SearchContents(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error)
SearchQuestions(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error)
SearchAnswers(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error)
@ -90,6 +91,11 @@ type Search interface {
DeleteContent(ctx context.Context, contentID string) error
}
type SearchDesc struct {
// A svg icon it wil be display in search result page
Icon string `json:"icon"`
}
var (
// CallUserCenter is a function that calls all registered parsers
CallSearch,