mirror of https://gitee.com/answerdev/answer.git
feat(search): add description for search
This commit is contained in:
parent
eef4b9df9e
commit
8aa58bc182
|
@ -8054,7 +8054,7 @@ const docTemplate = `{
|
||||||
"description": "search response",
|
"description": "search response",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/schema.SearchResp"
|
"$ref": "#/definitions/schema.SearchResults"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8107,7 +8107,7 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schema.SearchResp": {
|
"schema.SearchResults": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"object": {
|
"object": {
|
||||||
|
|
|
@ -39,7 +39,7 @@ func NewSearchController(
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param q query string true "query string"
|
// @Param q query string true "query string"
|
||||||
// @Param order query string true "order" Enums(newest,active,score,relevance)
|
// @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]
|
// @Router /answer/api/v1/search [get]
|
||||||
func (sc *SearchController) Search(ctx *gin.Context) {
|
func (sc *SearchController) Search(ctx *gin.Context) {
|
||||||
dto := schema.SearchDTO{}
|
dto := schema.SearchDTO{}
|
||||||
|
@ -65,12 +65,9 @@ func (sc *SearchController) Search(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, total, err := sc.searchService.Search(ctx, &dto)
|
|
||||||
if !isAdmin {
|
if !isAdmin {
|
||||||
sc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionSearch, unit)
|
sc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionSearch, unit)
|
||||||
}
|
}
|
||||||
handler.HandleResponse(ctx, err, schema.SearchListResp{
|
resp, err := sc.searchService.Search(ctx, &dto)
|
||||||
Total: total,
|
handler.HandleResponse(ctx, err, resp)
|
||||||
SearchResp: resp,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ func NewSearchRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo, userCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchContents search question and answer data
|
// 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)
|
words = filterWords(words)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -210,7 +210,7 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchQuestions search question data
|
// 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)
|
words = filterWords(words)
|
||||||
var (
|
var (
|
||||||
qfs = qFields
|
qfs = qFields
|
||||||
|
@ -319,7 +319,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchAnswers search answer data
|
// 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)
|
words = filterWords(words)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -428,7 +428,7 @@ func (sr *searchRepo) parseOrder(ctx context.Context, order string) (res string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseSearchPluginResult parse search plugin result
|
// 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 (
|
var (
|
||||||
qres []map[string][]byte
|
qres []map[string][]byte
|
||||||
res = make([]map[string][]byte, 0)
|
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
|
// 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 {
|
for _, r := range res {
|
||||||
var (
|
var (
|
||||||
objectKey,
|
objectKey,
|
||||||
|
@ -525,7 +525,7 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte)
|
||||||
AnswerCount: converter.StringToInt(string(r["answer_count"])),
|
AnswerCount: converter.StringToInt(string(r["answer_count"])),
|
||||||
StatusStr: status,
|
StatusStr: status,
|
||||||
}
|
}
|
||||||
resp = append(resp, schema.SearchResp{
|
resp = append(resp, schema.SearchResult{
|
||||||
ObjectType: objectKey,
|
ObjectType: objectKey,
|
||||||
Object: object,
|
Object: object,
|
||||||
})
|
})
|
||||||
|
|
|
@ -107,17 +107,17 @@ type TagResp struct {
|
||||||
Reserved bool `json:"reserved"`
|
Reserved bool `json:"reserved"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchResp struct {
|
type SearchResult struct {
|
||||||
// object_type
|
// object_type
|
||||||
ObjectType string `json:"object_type"`
|
ObjectType string `json:"object_type"`
|
||||||
// this object
|
// this object
|
||||||
Object SearchObject `json:"object"`
|
Object SearchObject `json:"object"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchListResp struct {
|
type SearchResp struct {
|
||||||
Total int64 `json:"count"`
|
Total int64 `json:"count"`
|
||||||
// search response
|
// search response
|
||||||
SearchResp []SearchResp `json:"list"`
|
SearchResults []SearchResult `json:"list"`
|
||||||
// extra fields
|
// search plugin desc
|
||||||
Extra interface{} `json:"extra"`
|
SearchPluginIcon string `json:"search_icon,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type SearchRepo interface {
|
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)
|
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.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.SearchResult, 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)
|
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.SearchResp, err error)
|
ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResult, err error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ func NewSearchService(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search search contents
|
// 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 {
|
if dto.Page < 1 {
|
||||||
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)
|
cond := ss.searchParser.ParseStructure(ctx, dto)
|
||||||
|
|
||||||
// check search plugin
|
// check search plugin
|
||||||
var s plugin.Search
|
var finder plugin.Search
|
||||||
_ = plugin.CallSearch(func(search plugin.Search) error {
|
_ = plugin.CallSearch(func(search plugin.Search) error {
|
||||||
s = search
|
finder = search
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
resp = &schema.SearchResp{}
|
||||||
// search plugin is not found, call system search
|
// search plugin is not found, call system search
|
||||||
if s == nil {
|
if finder == nil {
|
||||||
if cond.SearchAll() {
|
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() {
|
} 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() {
|
} 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
|
||||||
}
|
}
|
||||||
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
|
var res []plugin.SearchResult
|
||||||
|
resp = &schema.SearchResp{
|
||||||
|
SearchPluginIcon: finder.Description().Icon,
|
||||||
|
}
|
||||||
if cond.SearchAll() {
|
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() {
|
} 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() {
|
} 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)
|
resp.SearchResults, err = ss.searchRepo.ParseSearchPluginResult(ctx, res)
|
||||||
if err != nil {
|
return resp, err
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ const (
|
||||||
|
|
||||||
type Search interface {
|
type Search interface {
|
||||||
Base
|
Base
|
||||||
|
Description() SearchDesc
|
||||||
SearchContents(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error)
|
SearchContents(ctx context.Context, cond *SearchBasicCond) (res []SearchResult, total int64, err error)
|
||||||
SearchQuestions(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)
|
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
|
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 (
|
var (
|
||||||
// CallUserCenter is a function that calls all registered parsers
|
// CallUserCenter is a function that calls all registered parsers
|
||||||
CallSearch,
|
CallSearch,
|
||||||
|
|
Loading…
Reference in New Issue