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 search <关键词> [--top N] [--expanded <词>] [--symptom <词>] [--with-content] [--with-links] [--json] # 搜索知识库,支持关键词、扩展词、症状词`, 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 }