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/index/sqlite.go |   30 +++++++++++++++++++++++++++---
 1 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/internal/index/sqlite.go b/internal/index/sqlite.go
index ea306fb..043d483 100644
--- a/internal/index/sqlite.go
+++ b/internal/index/sqlite.go
@@ -156,9 +156,15 @@
 	for rows.Next() {
 		var st FileStat
 		var hash sql.NullString
-		if err := rows.Scan(&st.Path, &st.Size, &st.Mtime, &hash); err != nil {
+		var size, mtime sql.NullInt64
+		// 旧库迁移到 v2 后,老行的 size/mtime/content_hash 为 NULL(ALTER ADD COLUMN 不带值)。
+		// 用 Null 类型容忍 NULL:指纹缺失的行在对账时 size/mtime 必然不等,会走
+		// sha256 二次确认并重新写入指纹,实现自愈,不会误判为"未变更"。
+		if err := rows.Scan(&st.Path, &size, &mtime, &hash); err != nil {
 			return nil, err
 		}
+		st.Size = size.Int64
+		st.Mtime = mtime.Int64
 		st.ContentHash = hash.String
 		m[st.Path] = st
 	}
@@ -287,6 +293,24 @@
 	return links, nil
 }
 
+// GetUnresolvedLinks 某文档的悬空链接文本列表
+func (s *Store) GetUnresolvedLinks(path string) ([]string, error) {
+	rows, err := s.db.Query(`
+		SELECT u.link_text FROM unresolved_links u
+		JOIN nodes n ON n.id = u.from_node WHERE n.path = ?`, path)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+	var links []string
+	for rows.Next() {
+		var l string
+		rows.Scan(&l)
+		links = append(links, l)
+	}
+	return links, rows.Err()
+}
+
 // NodeInfo 节点基本信息(用于 GC)
 type NodeInfo struct {
 	ID   int64
@@ -464,7 +488,7 @@
 			visited[id] = true
 
 			query := `
-				SELECT id, from_node, to_node, relation, label
+				SELECT id, from_node, to_node, relation, label, provenance
 				FROM edges
 				WHERE from_node = ?
 			`
@@ -483,7 +507,7 @@
 			for rows.Next() {
 				var e graph.Edge
 				var edgeID int64
-				if err := rows.Scan(&edgeID, &e.FromNode, &e.ToNode, &e.Relation, &e.Label); err != nil {
+				if err := rows.Scan(&edgeID, &e.FromNode, &e.ToNode, &e.Relation, &e.Label, &e.Provenance); err != nil {
 					rows.Close()
 					return nil, fmt.Errorf("扫描边失败: %w", err)
 				}

--
Gitblit v1.10.0