From 5a2be87f658d01bc5b3b7ecdba92ac69bf09dcf7 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Thu, 03 Sep 2026 15:15:37 +0800
Subject: [PATCH] fix(search): 搜索准确性四连修——FTS5 MATCH 引号包裹(连字符不再被解析成 MINUS);KeywordSearch 截断按命中关键词数排序(高频 bigram 不再挤出强相关文档);原词奖励档(完整短语压过泛化 bigram);tags 字段真实参与评分(此前误用 Section)
---
internal/search/engine.go | 38 +++++++++++++++++++++++++++++++++++---
1 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/internal/search/engine.go b/internal/search/engine.go
index 13e2ff1..b21224d 100644
--- a/internal/search/engine.go
+++ b/internal/search/engine.go
@@ -81,6 +81,33 @@
textScore[r.ID] = score
}
+ // 原词奖励:候选由 bigram 召回时可能并不含用户原词("无法"×10 压过
+ // 含"无法开机"整词的文档)。原词真实出现在正文/标题/标签中时给强信号加分,
+ // 使"标题=原词"或"tags 含原词"的文档稳定压过只含泛化 bigram 的文档。
+ for _, r := range candidates {
+ content, _, _, err := store.GetNodeContent(r.ID)
+ if err != nil {
+ continue
+ }
+ lc := strings.ToLower(content)
+ titleL := strings.ToLower(r.Title)
+ for _, kw := range keywords {
+ kwL := strings.ToLower(kw)
+ hit := strings.Contains(lc, kwL) || strings.Contains(titleL, kwL)
+ if !hit {
+ for _, t := range r.Tags {
+ if strings.Contains(strings.ToLower(t), kwL) {
+ hit = true
+ break
+ }
+ }
+ }
+ if hit {
+ textScore[r.ID] += CalcScore(kw, "content", ScoreOriginal)
+ }
+ }
+ }
+
// 3. RWR 图质量(种子 = 候选前 20,全量加载邻接后按种子收敛)
seedIDs := make([]int64, 0, len(candidates))
for _, r := range candidates {
@@ -203,9 +230,14 @@
score += CalcScore(keyword, "title", scoreType)
}
- // 板块匹配
- if strings.Contains(strings.ToLower(r.Section), kw) {
- score += CalcScore(keyword, "tag", scoreType)
+ // 标签匹配(tags 字段真实参与评分;此前误用 Section,而 Section 恒为"其他")
+ if len(r.Tags) > 0 {
+ for _, t := range r.Tags {
+ if strings.Contains(strings.ToLower(t), kw) {
+ score += CalcScore(keyword, "tag", scoreType)
+ break
+ }
+ }
}
// 别名匹配(命中按 title 档计权,一次命中即计)
--
Gitblit v1.10.0