in internal/repo/search_common/search_repo.go [356:448]
func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs [][]string, accepted bool, questionID string, page, pageSize int, order string) (resp []*schema.SearchResult, total int64, err error) {
words = filterWords(words)
var (
afs = aFields
args = []interface{}{}
)
if order == "relevance" {
if len(words) > 0 {
afs, args = addRelevanceField([]string{"`answer`.`original_text`"}, words, afs)
} else {
order = "newest"
}
}
b := builder.MySQL().Select(afs...).From("`answer`").
LeftJoin("`question`", "`question`.id = `answer`.question_id")
b.Where(builder.Lt{"`question`.`status`": entity.QuestionStatusDeleted}).
And(builder.Lt{"`answer`.`status`": entity.AnswerStatusDeleted}).And(builder.Eq{"`question`.`show`": entity.QuestionShow})
args = append(args, entity.QuestionStatusDeleted, entity.AnswerStatusDeleted, entity.QuestionShow)
likeConA := builder.NewCond()
for _, word := range words {
likeConA = likeConA.Or(builder.Like{"`answer`.original_text", word})
args = append(args, "%"+word+"%")
}
b.Where(likeConA)
// check tag
for ti, tagID := range tagIDs {
ast := "tag_rel" + strconv.Itoa(ti)
b.Join("INNER", "tag_rel as "+ast, "question_id = "+ast+".object_id").
And(builder.Eq{
ast + ".status": entity.TagRelStatusAvailable,
}).
And(builder.In(ast+".tag_id", tagID))
args = append(args, entity.TagRelStatusAvailable)
for _, t := range tagID {
args = append(args, t)
}
}
// check limit accepted
if accepted {
b.Where(builder.Eq{"adopted": schema.AnswerAcceptedEnable})
args = append(args, schema.AnswerAcceptedEnable)
}
// check question id
if questionID != "" {
b.Where(builder.Eq{"question_id": questionID})
args = append(args, questionID)
}
queryArgs := []interface{}{}
countArgs := []interface{}{}
countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
if err != nil {
return
}
startNum := (page - 1) * pageSize
querySQL, _, err := b.OrderBy(sr.parseOrder(ctx, order)).Limit(pageSize, startNum).ToSQL()
if err != nil {
return
}
queryArgs = append(queryArgs, querySQL)
queryArgs = append(queryArgs, args...)
countArgs = append(countArgs, countSQL)
countArgs = append(countArgs, args...)
res, err := sr.data.DB.Context(ctx).Query(queryArgs...)
if err != nil {
return
}
tr, err := sr.data.DB.Context(ctx).Query(countArgs...)
if err != nil {
return
}
total = converter.StringToInt64(string(tr[0]["total"]))
resp, err = sr.parseResult(ctx, res, words)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
return
}