- Docs
- Data and storage
- Vector store
Vector store
Store embeddings and query closest matches by cosine similarity on sqlite, pgvector, or Qdrant.
vectorstore.VectorStore ranks embeddings by cosine similarity. Pair it with ai.Embed to embed, upsert, and query.
Quick start
Section titled “Quick start”db serves two backends through one name: an empty dsn selects embedded sqlite, a postgres URL selects pgvector. Move to qdrant for a purpose-built vector database at scale. Your code does not change.
VECTORSTORE_ADAPTER=dbVECTORSTORE_DIMENSION=1536VECTORSTORE_DSN=:memory:VECTORSTORE_ADAPTER=qdrantVECTORSTORE_URL=http://localhost:6333VECTORSTORE_API_KEY=dev-only-keyEnv vars: VECTORSTORE_ADAPTER, VECTORSTORE_DSN, VECTORSTORE_DIMENSION. dimension defaults to 1536 (OpenAI text-embedding-3-small) on pgvector and fixes the column size; Qdrant checks it only when set, and embedded sqlite learns it from the first write. A mismatched vector fails with vectorstore.ErrDimensionMismatch, and negatives are rejected. url needs a scheme and host. dedicated_pool: true opts out of per-DSN pool sharing. sqlite and pgvector alias db. See the vectorstore options.
Upsert and query vectors
Section titled “Upsert and query vectors”The container wires nothing: register the adapter first. VectorStore() resolves lazily, caches, and retries.
package main
import ( "context" "fmt"
vectorstoredb "github.com/zenta-dev/zever/adapters/vectorstore/db" "github.com/zenta-dev/zever/config" "github.com/zenta-dev/zever/container" "github.com/zenta-dev/zever/core/vectorstore")
func main() { vectorstoredb.Register() ctx := context.Background() c := container.New(config.Default()) defer c.Close(ctx)
vs, err := c.VectorStore() if err != nil { panic(err) } err = vs.UpsertBatch(ctx, []vectorstore.Vector{ {ID: "doc-1", Embedding: []float32{1, 0, 0}}, {ID: "doc-2", Embedding: []float32{0, 1, 0}}, }) if err != nil { panic(err) } matches, err := vs.Query(ctx, []float32{1, 0, 0}, 2) if err != nil { panic(err) } for _, m := range matches { fmt.Println("match:", m.ID, m.Score) }}match: doc-1 1match: doc-2 0Production checklist
Section titled “Production checklist”Queryranks by cosine similarity only. For hybrid ranking, combine with search.topK <= 0defaults to 10. Paginate explicitly for large result sets.- Use
UpsertBatchfor batches; loopingUpsertcosts one round trip per vector. - Empty embeddings are rejected before any I/O.
api_keynever appears in logs.
See the adapters matrix for db (legacy sqlite, pgvector) and qdrant.
Troubleshooting
Section titled “Troubleshooting”Query results look random
Cause: vectors come from a different model than the stored ones, or dimension was set wrong. Fix: align config with the model and re-upsert; an ErrDimensionMismatch error means the sizes differ.
Writes are slow at scale
Cause: you loop Upsert. Fix: use UpsertBatch.
qdrant fails to resolve
Cause: url lacks a scheme or host. Fix: check VECTORSTORE_URL for a missing http://.