vector_store.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package rag
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "strconv"
  7. "github.com/2930134478/AI-CS/backend/infra"
  8. )
  9. // ErrVectorStoreUnavailable 向量库未启用或未连接(写入/索引前会返回该错误)。
  10. var ErrVectorStoreUnavailable = errors.New("向量数据库未启用或未连接")
  11. // VectorStoreService 向量存储服务(业务层)
  12. type VectorStoreService struct {
  13. vectorStore *infra.VectorStore
  14. }
  15. // NewVectorStoreService 创建向量存储服务实例(vectorStore 可为 nil,表示无向量库降级模式)。
  16. func NewVectorStoreService(vectorStore *infra.VectorStore) *VectorStoreService {
  17. return &VectorStoreService{
  18. vectorStore: vectorStore,
  19. }
  20. }
  21. // IsAvailable 当前是否已连接可用的 Milvus 向量存储。
  22. func (s *VectorStoreService) IsAvailable() bool {
  23. return s != nil && s.vectorStore != nil
  24. }
  25. // UpsertVector 插入或更新单个向量
  26. func (s *VectorStoreService) UpsertVector(ctx context.Context, documentID string, knowledgeBaseID string, content string, chunkDBID string, vector []float32) error {
  27. if s.vectorStore == nil {
  28. return ErrVectorStoreUnavailable
  29. }
  30. return s.vectorStore.UpsertVector(ctx, documentID, knowledgeBaseID, content, chunkDBID, vector)
  31. }
  32. // UpsertVectors 批量插入或更新向量
  33. func (s *VectorStoreService) UpsertVectors(ctx context.Context, documentIDs []string, knowledgeBaseIDs []string, contents []string, vectors [][]float32, chunkDBIDs []string) error {
  34. if s.vectorStore == nil {
  35. return ErrVectorStoreUnavailable
  36. }
  37. return s.vectorStore.UpsertVectors(ctx, documentIDs, knowledgeBaseIDs, contents, vectors, chunkDBIDs)
  38. }
  39. // SearchVectors 搜索相似向量
  40. func (s *VectorStoreService) SearchVectors(ctx context.Context, queryVector []float32, topK int, knowledgeBaseID *string) ([]SearchResult, error) {
  41. if s.vectorStore == nil {
  42. return []SearchResult{}, nil
  43. }
  44. results, err := s.vectorStore.SearchVectors(ctx, queryVector, topK, knowledgeBaseID)
  45. if err != nil {
  46. return nil, fmt.Errorf("向量检索失败: %w", err)
  47. }
  48. searchResults := make([]SearchResult, len(results))
  49. for i, r := range results {
  50. searchResults[i] = SearchResult{
  51. DocumentID: r.DocumentID,
  52. KnowledgeBaseID: r.KnowledgeBaseID,
  53. Content: r.Content,
  54. Score: r.Score,
  55. }
  56. }
  57. return searchResults, nil
  58. }
  59. // DeleteVector 删除向量
  60. func (s *VectorStoreService) DeleteVector(ctx context.Context, documentID string) error {
  61. if s.vectorStore == nil {
  62. return nil
  63. }
  64. return s.vectorStore.DeleteVector(ctx, documentID)
  65. }
  66. // DeleteVectors 批量删除向量
  67. func (s *VectorStoreService) DeleteVectors(ctx context.Context, documentIDs []string) error {
  68. if s.vectorStore == nil {
  69. return nil
  70. }
  71. return s.vectorStore.DeleteVectors(ctx, documentIDs)
  72. }
  73. // DeleteVectorByChunkID 按 chunk_db_id 删除单条向量
  74. func (s *VectorStoreService) DeleteVectorByChunkID(ctx context.Context, chunkDBID string) error {
  75. if s.vectorStore == nil {
  76. return nil
  77. }
  78. return s.vectorStore.DeleteVectorByChunkID(ctx, chunkDBID)
  79. }
  80. // ConvertDocumentID 将 uint 转换为 string
  81. func ConvertDocumentID(id uint) string {
  82. return strconv.FormatUint(uint64(id), 10)
  83. }
  84. // ConvertKnowledgeBaseID 将 uint 转换为 string
  85. func ConvertKnowledgeBaseID(id uint) string {
  86. return strconv.FormatUint(uint64(id), 10)
  87. }