Upsert 将文档插入或更新到 pgvector 表。
(ctx context.Context, docs []vector.Document)
| 83 | |
| 84 | // Upsert 将文档插入或更新到 pgvector 表。 |
| 85 | func (s *Store) Upsert(ctx context.Context, docs []vector.Document) error { |
| 86 | if len(docs) == 0 { |
| 87 | return nil |
| 88 | } |
| 89 | |
| 90 | const tmpl = ` |
| 91 | INSERT INTO %s (id, namespace, embedding, metadata) |
| 92 | VALUES ($1, $2, $3, COALESCE($4, '{}'::jsonb)) |
| 93 | ON CONFLICT (id) DO UPDATE |
| 94 | SET namespace = EXCLUDED.namespace, |
| 95 | embedding = EXCLUDED.embedding, |
| 96 | metadata = EXCLUDED.metadata; |
| 97 | ` |
| 98 | query := fmt.Sprintf(tmpl, s.table) |
| 99 | |
| 100 | for _, d := range docs { |
| 101 | if d.ID == "" || len(d.Embedding) == 0 { |
| 102 | continue |
| 103 | } |
| 104 | if len(d.Embedding) != s.dim { |
| 105 | return fmt.Errorf("embedding dimension mismatch for id=%s: got %d, want %d", d.ID, len(d.Embedding), s.dim) |
| 106 | } |
| 107 | _, err := s.pool.Exec(ctx, query, d.ID, d.Namespace, float32SliceToPgVector(d.Embedding), d.Metadata) |
| 108 | if err != nil { |
| 109 | return fmt.Errorf("upsert vector %s: %w", d.ID, err) |
| 110 | } |
| 111 | } |
| 112 | return nil |
| 113 | } |
| 114 | |
| 115 | // Delete 从 pgvector 表中删除指定文档。 |
| 116 | func (s *Store) Delete(ctx context.Context, ids []string) error { |
nothing calls this directly
no test coverage detected