package cmd
|
|
import (
|
"fmt"
|
"os"
|
"strings"
|
|
"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 <关键词> [--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)
|
}
|
}
|
|
// 合并所有关键词(支持空格分隔和引号分隔)
|
var allKeywords []string
|
for _, arg := range args {
|
// 如果参数包含空格,按空格分割
|
parts := strings.Fields(arg)
|
allKeywords = append(allKeywords, parts...)
|
}
|
|
if len(allKeywords) == 0 {
|
return fmt.Errorf("请提供至少一个关键词")
|
}
|
|
// 执行搜索
|
opts := search.SearchOptions{
|
Expanded: expanded,
|
Symptom: symptom,
|
TopN: topN,
|
WithContent: withContent,
|
WithLinks: withLinks,
|
}
|
|
results, err := search.Search(store, allKeywords, 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
|
}
|