From 9c98026d5490ebb2ac9465d565319d77f6d505b4 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Sun, 26 Jul 2026 13:21:50 +0800
Subject: [PATCH] fix: 修复草稿创建时知识库搜索失败问题

---
 internal/index/fts.go |   67 +++++++++++++++++++++------------
 1 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/internal/index/fts.go b/internal/index/fts.go
index 5e67985..c06b250 100644
--- a/internal/index/fts.go
+++ b/internal/index/fts.go
@@ -3,9 +3,8 @@
 import (
 	"database/sql"
 	"encoding/json"
-	"strings"
+	"sort"
 )
-
 // FTSResult 全文搜索结果
 type FTSResult struct {
 	ID      int64
@@ -45,31 +44,51 @@
 		return nil, nil
 	}
 
-	// 构建 FTS5 查询
-	query := strings.Join(keywords, " OR ")
+	// 对每个关键词单独搜索,然后合并结果(去重)
+	// 这样即使某个关键词匹配不到,其他关键词也能找到结果
+	seen := make(map[int64]bool)
+	var allResults []FTSResult
 
-	rows, err := s.db.Query(`
-		SELECT n.id, n.path, n.title, n.section, fts.rank
-		FROM nodes_fts fts
-		JOIN nodes n ON n.id = fts.rowid
-		WHERE nodes_fts MATCH ?
-		ORDER BY fts.rank
-		LIMIT ?
-	`, query, limit)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-
-	var results []FTSResult
-	for rows.Next() {
-		var r FTSResult
-		if err := rows.Scan(&r.ID, &r.Path, &r.Title, &r.Section, &r.Rank); err != nil {
-			return nil, err
+	for _, kw := range keywords {
+		rows, err := s.db.Query(`
+			SELECT n.id, n.path, n.title, n.section, fts.rank
+			FROM nodes_fts fts
+			JOIN nodes n ON n.id = fts.rowid
+			WHERE nodes_fts MATCH ?
+			ORDER BY fts.rank
+			LIMIT ?
+		`, kw, limit)
+		if err != nil {
+			// 单个关键词搜索失败,跳过继续
+			continue
 		}
-		results = append(results, r)
+
+		for rows.Next() {
+			var r FTSResult
+			if err := rows.Scan(&r.ID, &r.Path, &r.Title, &r.Section, &r.Rank); err != nil {
+				rows.Close()
+				continue
+			}
+			// 去重
+			if !seen[r.ID] {
+				seen[r.ID] = true
+				allResults = append(allResults, r)
+			}
+		}
+		rows.Close()
 	}
-	return results, nil
+
+	// 按 rank 排序(FTS5 的 rank 越小越好)
+	sort.Slice(allResults, func(i, j int) bool {
+		return allResults[i].Rank < allResults[j].Rank
+	})
+
+	// 限制返回数量
+	if limit > 0 && len(allResults) > limit {
+		allResults = allResults[:limit]
+	}
+
+	return allResults, nil
 }
 
 // GetNodeContent 获取节点内容

--
Gitblit v1.9.1