diff --git a/internal/agent/tools/get_document_info.go b/internal/agent/tools/get_document_info.go index 69111c13..c5c7b9b2 100644 --- a/internal/agent/tools/get_document_info.go +++ b/internal/agent/tools/get_document_info.go @@ -139,7 +139,7 @@ func (t *GetDocumentInfoTool) Execute(ctx context.Context, args map[string]inter ListPagedChunksByKnowledgeID(ctx, t.tenantID, id, &types.Pagination{ Page: 1, PageSize: 1000, - }, []types.ChunkType{"text"}, "", "", "") + }, []types.ChunkType{"text"}, "", "", "", "") if err != nil { mu.Lock() results[id] = &docInfo{ diff --git a/internal/agent/tools/knowledge_search.go b/internal/agent/tools/knowledge_search.go index 3a68fd74..5ef49053 100644 --- a/internal/agent/tools/knowledge_search.go +++ b/internal/agent/tools/knowledge_search.go @@ -1052,7 +1052,7 @@ func (t *KnowledgeSearchTool) formatOutput( _, total, err := t.chunkService.GetRepository().ListPagedChunksByKnowledgeID(ctx, t.tenantID, result.KnowledgeID, &types.Pagination{Page: 1, PageSize: 1}, - []types.ChunkType{types.ChunkTypeText}, "", "", "", + []types.ChunkType{types.ChunkTypeText}, "", "", "", "", ) if err != nil { logger.Warnf( diff --git a/internal/agent/tools/list_knowledge_chunks.go b/internal/agent/tools/list_knowledge_chunks.go index 6ec00117..0747ee90 100644 --- a/internal/agent/tools/list_knowledge_chunks.go +++ b/internal/agent/tools/list_knowledge_chunks.go @@ -117,7 +117,7 @@ func (t *ListKnowledgeChunksTool) Execute(ctx context.Context, args map[string]i } chunks, total, err := t.chunkService.GetRepository().ListPagedChunksByKnowledgeID(ctx, - t.tenantID, knowledgeID, pagination, []types.ChunkType{types.ChunkTypeText, types.ChunkTypeFAQ}, "", "", "") + t.tenantID, knowledgeID, pagination, []types.ChunkType{types.ChunkTypeText, types.ChunkTypeFAQ}, "", "", "", "") if err != nil { return &types.ToolResult{ Success: false, diff --git a/internal/application/repository/chunk.go b/internal/application/repository/chunk.go index 78433e46..81216dbf 100644 --- a/internal/application/repository/chunk.go +++ b/internal/application/repository/chunk.go @@ -80,6 +80,7 @@ func (r *chunkRepository) ListPagedChunksByKnowledgeID( chunkType []types.ChunkType, tagID string, keyword string, + searchField string, sortOrder string, ) ([]*types.Chunk, int64, error) { var chunks []*types.Chunk @@ -97,7 +98,20 @@ func (r *chunkRepository) ListPagedChunksByKnowledgeID( } if keyword != "" { like := "%" + keyword + "%" - db = db.Where("(content LIKE ? OR metadata::text LIKE ?)", like, like) + switch searchField { + case "standard_question": + // Search only in standard_question field of metadata + db = db.Where("metadata->>'standard_question' ILIKE ?", like) + case "similar_questions": + // Search in similar_questions array of metadata + db = db.Where("metadata->'similar_questions'::text ILIKE ?", like) + case "answers": + // Search in answers array of metadata + db = db.Where("metadata->'answers'::text ILIKE ?", like) + default: + // Search in all fields (content and metadata) + db = db.Where("(content ILIKE ? OR metadata::text ILIKE ?)", like, like) + } } return db } diff --git a/internal/application/service/agent_service.go b/internal/application/service/agent_service.go index b6cb1940..82fac0f4 100644 --- a/internal/application/service/agent_service.go +++ b/internal/application/service/agent_service.go @@ -337,7 +337,7 @@ func (s *agentService) getKnowledgeBaseInfos(ctx context.Context, kbIDs []string pageResult, err := s.knowledgeService.ListFAQEntries(ctx, kbID, &types.Pagination{ Page: 1, PageSize: 10, - }, "", "", "") + }, "", "", "", "") if err == nil && pageResult != nil { docCount = int(pageResult.Total) if entries, ok := pageResult.Data.([]*types.FAQEntry); ok { diff --git a/internal/application/service/chunk.go b/internal/application/service/chunk.go index 7c37afe5..c73107e7 100644 --- a/internal/application/service/chunk.go +++ b/internal/application/service/chunk.go @@ -152,6 +152,7 @@ func (s *chunkService) ListPagedChunksByKnowledgeID(ctx context.Context, "", "", "", + "", ) if err != nil { logger.ErrorWithFields(ctx, err, map[string]interface{}{ diff --git a/internal/application/service/knowledge.go b/internal/application/service/knowledge.go index 8d87686e..3d21dc89 100644 --- a/internal/application/service/knowledge.go +++ b/internal/application/service/knowledge.go @@ -2549,6 +2549,7 @@ func (s *knowledgeService) CloneChunk(ctx context.Context, src, dst *types.Knowl "", "", "", + "", ) chunkPage++ if err != nil { @@ -2643,7 +2644,7 @@ func (s *knowledgeService) CloneChunk(ctx context.Context, src, dst *types.Knowl // ListFAQEntries lists FAQ entries under a FAQ knowledge base. func (s *knowledgeService) ListFAQEntries(ctx context.Context, - kbID string, page *types.Pagination, tagID string, keyword string, sortOrder string, + kbID string, page *types.Pagination, tagID string, keyword string, searchField string, sortOrder string, ) (*types.PageResult, error) { if page == nil { page = &types.Pagination{} @@ -2663,7 +2664,7 @@ func (s *knowledgeService) ListFAQEntries(ctx context.Context, } chunkType := []types.ChunkType{types.ChunkTypeFAQ} chunks, total, err := s.chunkRepo.ListPagedChunksByKnowledgeID( - ctx, tenantID, faqKnowledge.ID, page, chunkType, tagID, keyword, sortOrder, + ctx, tenantID, faqKnowledge.ID, page, chunkType, tagID, keyword, searchField, sortOrder, ) if err != nil { return nil, err diff --git a/internal/handler/faq.go b/internal/handler/faq.go index ca3354f0..a481648f 100644 --- a/internal/handler/faq.go +++ b/internal/handler/faq.go @@ -28,12 +28,13 @@ func NewFAQHandler(knowledgeService interfaces.KnowledgeService) *FAQHandler { // @Tags FAQ管理 // @Accept json // @Produce json -// @Param id path string true "知识库ID" -// @Param page query int false "页码" -// @Param page_size query int false "每页数量" -// @Param tag_id query string false "标签ID筛选" -// @Param keyword query string false "关键词搜索" -// @Param sort_order query string false "排序方式: asc(按更新时间正序), 默认按更新时间倒序" +// @Param id path string true "知识库ID" +// @Param page query int false "页码" +// @Param page_size query int false "每页数量" +// @Param tag_id query string false "标签ID筛选" +// @Param keyword query string false "关键词搜索" +// @Param search_field query string false "搜索字段: standard_question(标准问题), similar_questions(相似问法), answers(答案), 默认搜索全部" +// @Param sort_order query string false "排序方式: asc(按更新时间正序), 默认按更新时间倒序" // @Success 200 {object} map[string]interface{} "FAQ列表" // @Failure 400 {object} errors.AppError "请求参数错误" // @Security Bearer @@ -50,9 +51,10 @@ func (h *FAQHandler) ListEntries(c *gin.Context) { tagID := secutils.SanitizeForLog(c.Query("tag_id")) keyword := secutils.SanitizeForLog(c.Query("keyword")) + searchField := secutils.SanitizeForLog(c.Query("search_field")) sortOrder := secutils.SanitizeForLog(c.Query("sort_order")) - result, err := h.knowledgeService.ListFAQEntries(ctx, secutils.SanitizeForLog(c.Param("id")), &page, tagID, keyword, sortOrder) + result, err := h.knowledgeService.ListFAQEntries(ctx, secutils.SanitizeForLog(c.Param("id")), &page, tagID, keyword, searchField, sortOrder) if err != nil { logger.ErrorWithFields(ctx, err, nil) c.Error(err) diff --git a/internal/types/interfaces/chunk.go b/internal/types/interfaces/chunk.go index 400b35d2..a704bb00 100644 --- a/internal/types/interfaces/chunk.go +++ b/internal/types/interfaces/chunk.go @@ -19,6 +19,7 @@ type ChunkRepository interface { // ListPagedChunksByKnowledgeID lists paged chunks by knowledge id. // When tagID is non-empty, results are filtered by tag_id. // sortOrder: "asc" for time ascending (updated_at ASC), default is time descending (updated_at DESC) + // searchField: specifies which field to search in (for FAQ: "standard_question", "similar_questions", "answers", "" for all) ListPagedChunksByKnowledgeID( ctx context.Context, tenantID uint64, @@ -27,6 +28,7 @@ type ChunkRepository interface { chunkType []types.ChunkType, tagID string, keyword string, + searchField string, sortOrder string, ) ([]*types.Chunk, int64, error) ListChunkByParentID(ctx context.Context, tenantID uint64, parentID string) ([]*types.Chunk, error) diff --git a/internal/types/interfaces/knowledge.go b/internal/types/interfaces/knowledge.go index bd50bda8..ac1bf388 100644 --- a/internal/types/interfaces/knowledge.go +++ b/internal/types/interfaces/knowledge.go @@ -74,6 +74,7 @@ type KnowledgeService interface { UpdateImageInfo(ctx context.Context, knowledgeID string, chunkID string, imageInfo string) error // ListFAQEntries lists FAQ entries under a FAQ knowledge base. // When tagID is non-empty, results are filtered by tag_id on FAQ chunks. + // searchField: specifies which field to search in ("standard_question", "similar_questions", "answers", "" for all) // sortOrder: "asc" for time ascending (updated_at ASC), default is time descending (updated_at DESC) ListFAQEntries( ctx context.Context, @@ -81,6 +82,7 @@ type KnowledgeService interface { page *types.Pagination, tagID string, keyword string, + searchField string, sortOrder string, ) (*types.PageResult, error) // UpsertFAQEntries imports or appends FAQ entries asynchronously.