From 09c2a03cefa687832257d3b816da50db3cfcc0f2 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Sat, 25 Jul 2026 23:48:11 +0800
Subject: [PATCH] feat: 实现输出格式化
---
internal/index/fts.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 101 insertions(+), 0 deletions(-)
diff --git a/internal/index/fts.go b/internal/index/fts.go
new file mode 100644
index 0000000..5e67985
--- /dev/null
+++ b/internal/index/fts.go
@@ -0,0 +1,101 @@
+package index
+
+import (
+ "database/sql"
+ "encoding/json"
+ "strings"
+)
+
+// FTSResult 全文搜索结果
+type FTSResult struct {
+ ID int64
+ Path string
+ Title string
+ Section string
+ Rank float64
+}
+
+// CreateFTS 创建 FTS5 虚拟表
+func (s *Store) CreateFTS() error {
+ _, err := s.db.Exec(`
+ CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
+ title,
+ content,
+ tags,
+ entities,
+ content='nodes',
+ content_rowid='id'
+ )
+ `)
+ return err
+}
+
+// PopulateFTS 填充 FTS 索引
+func (s *Store) PopulateFTS() error {
+ _, err := s.db.Exec(`
+ INSERT INTO nodes_fts(rowid, title, content, tags, entities)
+ SELECT id, title, content_fts, tags, entities FROM nodes
+ `)
+ return err
+}
+
+// FTSSearch 全文搜索
+func (s *Store) FTSSearch(keywords []string, limit int) ([]FTSResult, error) {
+ if len(keywords) == 0 {
+ return nil, nil
+ }
+
+ // 构建 FTS5 查询
+ query := strings.Join(keywords, " OR ")
+
+ 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
+ }
+ results = append(results, r)
+ }
+ return results, nil
+}
+
+// GetNodeContent 获取节点内容
+func (s *Store) GetNodeContent(id int64) (string, []string, []string, error) {
+ var content, tagsJSON, entitiesJSON string
+ err := s.db.QueryRow("SELECT content_fts, tags, entities FROM nodes WHERE id = ?", id).
+ Scan(&content, &tagsJSON, &entitiesJSON)
+ if err == sql.ErrNoRows {
+ return "", nil, nil, nil
+ }
+ if err != nil {
+ return "", nil, nil, err
+ }
+
+ // 解析 JSON 数组
+ var tags, entities []string
+ if tagsJSON != "" {
+ if err := json.Unmarshal([]byte(tagsJSON), &tags); err != nil {
+ tags = nil
+ }
+ }
+ if entitiesJSON != "" {
+ if err := json.Unmarshal([]byte(entitiesJSON), &entities); err != nil {
+ entities = nil
+ }
+ }
+
+ return content, tags, entities, nil
+}
--
Gitblit v1.9.1