ax_rd
4 hours ago 60eb89c12ee0661785395bff90940204b16dcb3a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package search
 
// containsCJK 是否含 CJK 统一表意文字
func containsCJK(s string) bool {
    for _, r := range s {
        if r >= 0x4E00 && r <= 0x9FFF {
            return true
        }
    }
    return false
}
 
// ExpandCJKKeywords 关键词展开(search 与 explore 共享):CJK 长词(>3 字符)
// 拆成 bigram 滑动窗口(FTS5 unicode61 把连续中文当整串单 token,长复合词整串
// LIKE 匹配不到;文档里 "电子秤补气失败" 通常不是连续子串,bigram 才能命中)。
// 原词保留(段落命中判断时原词更精确)。末尾去重保序(原词在前、展开词在后)。
func ExpandCJKKeywords(keywords []string) []string {
    var out []string
    for _, kw := range keywords {
        out = append(out, kw)
        if containsCJK(kw) && len([]rune(kw)) > 3 {
            runes := []rune(kw)
            for i := 0; i+1 < len(runes); i++ {
                bg := string(runes[i : i+2])
                out = append(out, bg)
            }
        }
    }
    // 去重保序(原词在前、展开词在后):避免 bigram 与原词重复时 text 分重复计权
    var dedup []string
    seen := make(map[string]bool, len(out))
    for _, kw := range out {
        if !seen[kw] {
            seen[kw] = true
            dedup = append(dedup, kw)
        }
    }
    return dedup
}