internal/index/fts.go
@@ -14,25 +14,46 @@
   Rank    float64
}
// CreateFTS 创建 FTS5 虚拟表
// CreateFTS 创建 FTS5 虚拟表(external-content 模式,由触发器增量维护)
// 注意:external-content 模式下 FTS 列名必须与 content 表列名一致,
// 故 content 列对应 nodes 表的 content_fts 列
func (s *Store) CreateFTS() error {
   _, err := s.db.Exec(`
      CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
         title,
         content,
         tags,
         entities
      )
   `)
   return err
         title, content_fts, tags, aliases,
         content='nodes', content_rowid='id'
      )`)
   if err != nil {
      return err
   }
   // 触发器:nodes 的增删改同步维护 FTS
   triggers := []string{
      `CREATE TRIGGER IF NOT EXISTS nodes_fts_ai AFTER INSERT ON nodes BEGIN
         INSERT INTO nodes_fts(rowid, title, content_fts, tags, aliases)
         VALUES (new.id, new.title, new.content_fts, new.tags, new.aliases);
      END`,
      `CREATE TRIGGER IF NOT EXISTS nodes_fts_ad AFTER DELETE ON nodes BEGIN
         INSERT INTO nodes_fts(nodes_fts, rowid, title, content_fts, tags, aliases)
         VALUES ('delete', old.id, old.title, old.content_fts, old.tags, old.aliases);
      END`,
      `CREATE TRIGGER IF NOT EXISTS nodes_fts_au AFTER UPDATE ON nodes BEGIN
         INSERT INTO nodes_fts(nodes_fts, rowid, title, content_fts, tags, aliases)
         VALUES ('delete', old.id, old.title, old.content_fts, old.tags, old.aliases);
         INSERT INTO nodes_fts(rowid, title, content_fts, tags, aliases)
         VALUES (new.id, new.title, new.content_fts, new.tags, new.aliases);
      END`,
   }
   for _, t := range triggers {
      if _, err := s.db.Exec(t); err != nil {
         return err
      }
   }
   return nil
}
// PopulateFTS 填充 FTS 索引
// PopulateFTS 全量重灌 FTS(external-content 模式专用语法)
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
   `)
   _, err := s.db.Exec(`INSERT INTO nodes_fts(nodes_fts) VALUES('rebuild')`)
   return err
}