72 lines
2.2 KiB
Go
72 lines
2.2 KiB
Go
package srv_search
|
||
|
||
import (
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
// 分隔符:空格、英文逗号、中文逗号、顿号、斜杠、竖线
|
||
var kwSplitRe = regexp.MustCompile(`[\s,,、/|]+`)
|
||
|
||
// ParseKeywords 解析搜索字符串为关键词列表。
|
||
// 规则:去除首尾空格,转小写,按空格/逗号/顿号/斜杠/竖线分割,过滤空串。
|
||
func ParseKeywords(q string) []string {
|
||
q = strings.TrimSpace(q)
|
||
if q == "" {
|
||
return nil
|
||
}
|
||
parts := kwSplitRe.Split(strings.ToLower(q), -1)
|
||
result := make([]string, 0, len(parts))
|
||
for _, p := range parts {
|
||
if p = strings.TrimSpace(p); p != "" {
|
||
result = append(result, p)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
// buildMultiKeywordQuery 构建多关键词 ES bool should 查询(关键词之间 OR 关系)。
|
||
// 每个关键词同时生成两个子句:
|
||
// - 精确 multi_match(权重更高,boost=2)
|
||
// - 模糊 multi_match(fuzziness=AUTO,prefix_length=1),覆盖拼写错误/多余字符等场景
|
||
//
|
||
// 示例:ChatGPTT→ChatGPT(1次编辑)、midjorny→midjourney(2次编辑)、数智人→数字人(1次编辑)
|
||
func buildMultiKeywordQuery(keywords []string, fields []string, from, size int) map[string]interface{} {
|
||
shouldClauses := make([]map[string]interface{}, 0, len(keywords)*2)
|
||
for _, kw := range keywords {
|
||
// 精确匹配,分数更高
|
||
shouldClauses = append(shouldClauses, map[string]interface{}{
|
||
"multi_match": map[string]interface{}{
|
||
"query": kw,
|
||
"fields": fields,
|
||
"type": "best_fields",
|
||
"boost": 2,
|
||
},
|
||
})
|
||
// 模糊匹配:AUTO fuzziness(长度≥6时允许2次编辑),prefix_length=1 避免过度误召回
|
||
shouldClauses = append(shouldClauses, map[string]interface{}{
|
||
"multi_match": map[string]interface{}{
|
||
"query": kw,
|
||
"fields": fields,
|
||
"type": "best_fields",
|
||
"fuzziness": "AUTO",
|
||
"prefix_length": 1,
|
||
"fuzzy_rewrite": "constant_score_blended",
|
||
},
|
||
})
|
||
}
|
||
return map[string]interface{}{
|
||
"from": from,
|
||
"size": size,
|
||
"query": map[string]interface{}{
|
||
"bool": map[string]interface{}{
|
||
"should": shouldClauses,
|
||
"minimum_should_match": 1,
|
||
},
|
||
},
|
||
"sort": []map[string]interface{}{
|
||
{"_score": map[string]interface{}{"order": "desc"}},
|
||
},
|
||
}
|
||
}
|