diff --git a/internal/controller/question_controller.go b/internal/controller/question_controller.go index 71fc24ec..80b56f45 100644 --- a/internal/controller/question_controller.go +++ b/internal/controller/question_controller.go @@ -686,9 +686,9 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) { handler.HandleResponse(ctx, nil, nil) } -// SearchByTitleLike add question title like -// @Summary add question title like -// @Description add question title like +// GetSimilarQuestions fuzzy query similar questions based on title +// @Summary fuzzy query similar questions based on title +// @Description fuzzy query similar questions based on title // @Tags Question // @Accept json // @Produce json @@ -696,10 +696,9 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) { // @Param title query string true "title" default(string) // @Success 200 {object} handler.RespBody // @Router /answer/api/v1/question/similar [get] -func (qc *QuestionController) SearchByTitleLike(ctx *gin.Context) { +func (qc *QuestionController) GetSimilarQuestions(ctx *gin.Context) { title := ctx.Query("title") - userID := middleware.GetLoginUserIDFromContext(ctx) - resp, err := qc.questionService.SearchByTitleLike(ctx, title, userID) + resp, err := qc.questionService.GetQuestionsByTitle(ctx, title) handler.HandleResponse(ctx, err, resp) } diff --git a/internal/controller/tag_controller.go b/internal/controller/tag_controller.go index 55edc8ec..331b2a18 100644 --- a/internal/controller/tag_controller.go +++ b/internal/controller/tag_controller.go @@ -45,7 +45,6 @@ func (tc *TagController) SearchTagLike(ctx *gin.Context) { if handler.BindAndCheck(ctx, req) { return } - req.IsAdmin = middleware.GetIsAdminFromContext(ctx) resp, err := tc.tagCommonService.SearchTagLike(ctx, req) handler.HandleResponse(ctx, err, resp) } diff --git a/internal/repo/question/question_repo.go b/internal/repo/question/question_repo.go index 299b8451..129af992 100644 --- a/internal/repo/question/question_repo.go +++ b/internal/repo/question/question_repo.go @@ -186,10 +186,15 @@ func (qr *questionRepo) GetQuestion(ctx context.Context, id string) ( return } -// GetTagBySlugName get tag by slug name -func (qr *questionRepo) SearchByTitleLike(ctx context.Context, title string) (questionList []*entity.Question, err error) { +// GetQuestionsByTitle get question list by title +func (qr *questionRepo) GetQuestionsByTitle(ctx context.Context, title string, pageSize int) ( + questionList []*entity.Question, err error) { questionList = make([]*entity.Question, 0) - err = qr.data.DB.Context(ctx).Table("question").Where("title like ?", "%"+title+"%").Limit(10, 0).Find(&questionList) + session := qr.data.DB.Context(ctx) + session.Where("status != ?", entity.QuestionStatusDeleted) + session.Where("title like ?", "%"+title+"%") + session.Limit(pageSize) + err = session.Find(&questionList) if err != nil { return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } diff --git a/internal/repo/tag_common/tag_common_repo.go b/internal/repo/tag_common/tag_common_repo.go index a7380028..9218ba47 100644 --- a/internal/repo/tag_common/tag_common_repo.go +++ b/internal/repo/tag_common/tag_common_repo.go @@ -3,6 +3,7 @@ package tag_common import ( "context" "fmt" + "strings" "github.com/answerdev/answer/internal/base/data" "github.com/answerdev/answer/internal/base/pager" @@ -56,19 +57,28 @@ func (tr *tagCommonRepo) GetTagBySlugName(ctx context.Context, slugName string) } // GetTagListByName get tag list all like name -func (tr *tagCommonRepo) GetTagListByName(ctx context.Context, name string, hasReserved bool) (tagList []*entity.Tag, err error) { - tagList = make([]*entity.Tag, 0) +func (tr *tagCommonRepo) GetTagListByName(ctx context.Context, name string, recommend, reserved bool) (tagList []*entity.Tag, err error) { cond := &entity.Tag{} - session := tr.data.DB.Context(ctx).Where("") - if name != "" { - session.Where("slug_name LIKE LOWER(?) or display_name LIKE ?", name+"%", name+"%") - } else { - session.UseBool("recommend") + session := tr.data.DB.Context(ctx) + if len(name) > 0 { + session.Where("slug_name LIKE ? OR display_name LIKE ?", strings.ToLower(name)+"%", name+"%") + } + var columns []string + if recommend { + columns = append(columns, "recommend") cond.Recommend = true } + if reserved { + columns = append(columns, "reserved") + cond.Reserved = true + } + if len(columns) > 0 { + session.UseBool(columns...) + } session.Where(builder.Eq{"status": entity.TagStatusAvailable}) - session.Asc("slug_name") - err = session.OrderBy("recommend desc,reserved desc,id desc").Find(&tagList, cond) + + tagList = make([]*entity.Tag, 0) + err = session.OrderBy("recommend DESC,reserved DESC,slug_name ASC").Find(&tagList, cond) if err != nil { err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 8124648e..4f196042 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -203,7 +203,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) { r.PUT("/question/status", a.questionController.CloseQuestion) r.PUT("/question/operation", a.questionController.OperationQuestion) r.PUT("/question/reopen", a.questionController.ReopenQuestion) - r.GET("/question/similar", a.questionController.SearchByTitleLike) + r.GET("/question/similar", a.questionController.GetSimilarQuestions) // answer r.POST("/answer", a.answerController.Add) diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index 84a6c880..e77243eb 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -40,7 +40,7 @@ type QuestionRepo interface { UpdateQuestionStatus(ctx context.Context, question *entity.Question) (err error) UpdateQuestionStatusWithOutUpdateTime(ctx context.Context, question *entity.Question) (err error) UpdateQuestionOperation(ctx context.Context, question *entity.Question) (err error) - SearchByTitleLike(ctx context.Context, title string) (questionList []*entity.Question, err error) + GetQuestionsByTitle(ctx context.Context, title string, pageSize int) (questionList []*entity.Question, err error) UpdatePvCount(ctx context.Context, questionID string) (err error) UpdateAnswerCount(ctx context.Context, questionID string, num int) (err error) UpdateCollectionCount(ctx context.Context, questionID string, num int) (err error) diff --git a/internal/service/question_service.go b/internal/service/question_service.go index 48dbffcd..00bdf299 100644 --- a/internal/service/question_service.go +++ b/internal/service/question_service.go @@ -1103,14 +1103,18 @@ func (qs *QuestionService) SearchUserTopList(ctx context.Context, userName strin return userQuestionlist, userAnswerlist, nil } -// SearchByTitleLike -func (qs *QuestionService) SearchByTitleLike(ctx context.Context, title string, loginUserID string) ([]*schema.QuestionBaseInfo, error) { - list := make([]*schema.QuestionBaseInfo, 0) - dblist, err := qs.questionRepo.SearchByTitleLike(ctx, title) - if err != nil { - return list, err +// GetQuestionsByTitle get questions by title +func (qs *QuestionService) GetQuestionsByTitle(ctx context.Context, title string) ( + resp []*schema.QuestionBaseInfo, err error) { + resp = make([]*schema.QuestionBaseInfo, 0) + if len(title) == 0 { + return resp, nil } - for _, question := range dblist { + questions, err := qs.questionRepo.GetQuestionsByTitle(ctx, title, 10) + if err != nil { + return resp, err + } + for _, question := range questions { item := &schema.QuestionBaseInfo{} item.ID = question.ID item.Title = question.Title @@ -1125,10 +1129,9 @@ func (qs *QuestionService) SearchByTitleLike(ctx context.Context, title string, if question.AcceptedAnswerID != "0" { item.AcceptedAnswer = true } - list = append(list, item) + resp = append(resp, item) } - - return list, nil + return resp, nil } // SimilarQuestion diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index b57eb240..60cc9875 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -24,7 +24,7 @@ type TagCommonRepo interface { AddTagList(ctx context.Context, tagList []*entity.Tag) (err error) GetTagListByIDs(ctx context.Context, ids []string) (tagList []*entity.Tag, err error) GetTagBySlugName(ctx context.Context, slugName string) (tagInfo *entity.Tag, exist bool, err error) - GetTagListByName(ctx context.Context, name string, hasReserved bool) (tagList []*entity.Tag, err error) + GetTagListByName(ctx context.Context, name string, recommend, reserved bool) (tagList []*entity.Tag, err error) GetTagListByNames(ctx context.Context, names []string) (tagList []*entity.Tag, err error) GetTagByID(ctx context.Context, tagID string, includeDeleted bool) (tag *entity.Tag, exist bool, err error) GetTagPage(ctx context.Context, page, pageSize int, tag *entity.Tag, queryCond string) (tagList []*entity.Tag, total int64, err error) @@ -86,7 +86,7 @@ func NewTagCommonService( // SearchTagLike get tag list all func (ts *TagCommonService) SearchTagLike(ctx context.Context, req *schema.SearchTagLikeReq) (resp []schema.SearchTagLikeResp, err error) { - tags, err := ts.tagCommonRepo.GetTagListByName(ctx, req.Tag, req.IsAdmin) + tags, err := ts.tagCommonRepo.GetTagListByName(ctx, req.Tag, len(req.Tag) == 0, false) if err != nil { return } @@ -97,35 +97,39 @@ func (ts *TagCommonService) SearchTagLike(ctx context.Context, req *schema.Searc mainTagId = append(mainTagId, converter.IntToString(tag.MainTagID)) } } - mainTagList, err := ts.tagCommonRepo.GetTagListByIDs(ctx, mainTagId) - if err != nil { - return - } mainTagMap := make(map[string]*entity.Tag) - for _, tag := range mainTagList { - mainTagMap[tag.ID] = tag - } - for _, tag := range tags { - if tag.MainTagID != 0 { - _, ok := mainTagMap[converter.IntToString(tag.MainTagID)] - if ok { - tag.SlugName = mainTagMap[converter.IntToString(tag.MainTagID)].SlugName - tag.DisplayName = mainTagMap[converter.IntToString(tag.MainTagID)].DisplayName - tag.Reserved = mainTagMap[converter.IntToString(tag.MainTagID)].Reserved - tag.Recommend = mainTagMap[converter.IntToString(tag.MainTagID)].Recommend - } + if len(mainTagId) > 0 { + mainTagList, err := ts.tagCommonRepo.GetTagListByIDs(ctx, mainTagId) + if err != nil { + return nil, err + } + for _, tag := range mainTagList { + mainTagMap[tag.ID] = tag } } - RepetitiveTag := make(map[string]bool) for _, tag := range tags { - if _, ok := RepetitiveTag[tag.SlugName]; !ok { + if tag.MainTagID == 0 { + continue + } + mainTagID := converter.IntToString(tag.MainTagID) + if _, ok := mainTagMap[mainTagID]; ok { + tag.SlugName = mainTagMap[mainTagID].SlugName + tag.DisplayName = mainTagMap[mainTagID].DisplayName + tag.Reserved = mainTagMap[mainTagID].Reserved + tag.Recommend = mainTagMap[mainTagID].Recommend + } + } + resp = make([]schema.SearchTagLikeResp, 0) + repetitiveTag := make(map[string]bool) + for _, tag := range tags { + if _, ok := repetitiveTag[tag.SlugName]; !ok { item := schema.SearchTagLikeResp{} item.SlugName = tag.SlugName item.DisplayName = tag.DisplayName item.Recommend = tag.Recommend item.Reserved = tag.Reserved resp = append(resp, item) - RepetitiveTag[tag.SlugName] = true + repetitiveTag[tag.SlugName] = true } } return resp, nil