package cmd import ( "fmt" "os" "github.com/aisim/kb-cli/internal/index" "github.com/aisim/kb-cli/internal/search" "github.com/aisim/kb-cli/internal/output" "github.com/spf13/cobra" ) var ( expanded []string symptom []string topN int jsonOut bool withContent bool withLinks bool ) var searchCmd = &cobra.Command{ Use: "search [keywords...]", Short: "搜索知识库", Long: `# search - 搜索 kb-cli search <关键词> [flags] 参数: <关键词> 搜索关键词(必填,支持多个) --top N 返回前 N 条结果(默认 10) --expanded <词> 扩展词(提升相关实体权重,支持多个) --symptom <词> 症状词(针对具体症状,支持多个) --with-content 返回完整文件内容 --with-links 显示关联文档链接 --json JSON 格式输出 全局参数: --vault <路径> 知识库根目录(默认:~/aisim/note/001/笔记001) --db <路径> 索引数据库路径(默认:~/.cache/kb-cli/kb.db)`, Args: cobra.MinimumNArgs(1), RunE: runSearch, } func init() { rootCmd.AddCommand(searchCmd) searchCmd.Flags().StringSliceVar(&expanded, "expanded", nil, "扩展词(提升相关实体权重)") searchCmd.Flags().StringSliceVar(&symptom, "symptom", nil, "症状词(针对具体症状)") searchCmd.Flags().IntVar(&topN, "top", 10, "返回前 N 条结果") searchCmd.Flags().BoolVar(&jsonOut, "json", false, "JSON 格式输出") searchCmd.Flags().BoolVar(&withContent, "with-content", false, "返回完整文件内容") searchCmd.Flags().BoolVar(&withLinks, "with-links", false, "显示关联文档链接") } func runSearch(cmd *cobra.Command, args []string) error { // 打开索引 store, err := index.Open(dbPath) if err != nil { return fmt.Errorf("打开索引失败: %w", err) } defer store.Close() // 检查是否需要重建索引 needsRebuild, commit, err := index.NeedsRebuild(store, vaultPath) if err != nil { return fmt.Errorf("检查索引状态失败: %w", err) } if needsRebuild { fmt.Fprintln(os.Stderr, "索引过期,正在重建...") if err := rebuildIndex(store, commit); err != nil { return fmt.Errorf("重建索引失败: %w", err) } } // 执行搜索 opts := search.SearchOptions{ Expanded: expanded, Symptom: symptom, TopN: topN, WithContent: withContent, WithLinks: withLinks, } results, err := search.Search(store, args, opts) if err != nil { return fmt.Errorf("搜索失败: %w", err) } // 输出结果 if jsonOut { jsonStr, err := output.FormatJSON(results) if err != nil { return err } fmt.Println(jsonStr) } else { fmt.Print(output.FormatTable(results)) } return nil }