agrag.vectordb.qdrant.QdrantVectorStore
QdrantVectorStore(*, settings:QdrantSettings | None = None, sparse_embedder:SparseEmbedder | None = None, client:Any | None = None, models:Any | None = None, tracer:Tracer | None = None) -> None
Bases: VectorStore
A VectorStore backed by Qdrant, including native hybrid search.
The client connects lazily on first use, so constructing the store does not
open a network connection. Hybrid search builds its sparse query with a
SparseEmbedder that defaults to FastEmbed BM25 and loads only when a
hybrid call first runs, not at construction.
Functions:
- close – Release the backend connection.
- collection_exists – Report whether a collection exists.
- commit_pending – Promote one job's staged records to committed records.
- count – Count records in a collection.
- delete – Delete records by id.
- delete_collection – Delete a collection and all its points.
- delete_pending – Delete one job's staged records, leaving committed records alone.
- ensure_collection – Create the collection if it does not exist.
- hybrid_search – Search by dense vector and keyword text, fused by a weighted blend.
- initialize – Check connectivity and authentication.
- invalidate_collection – Drop cached hybrid-state and distance-metric knowledge of a collection.
- retrieve – Fetch records by id.
- scroll – Iterate records in a collection, in batches.
- search – Search by dense vector only.
- upsert – Write or overwrite records in a collection.
Parameters:
- settings (
QdrantSettings | None) – Qdrant connection settings. Defaults toQdrantSettings(). - sparse_embedder (
SparseEmbedder | None) – The sparse embedder hybrid search uses. Defaults to a lazily-builtFastEmbedBM25Embedder. - client (
Any | None) – A pre-builtAsyncQdrantClient, for tests. When set,__init__imports nothing and the store calls this object directly instead of building one. - models (
Any | None) – Theqdrant_client.modelsmodule, for tests. Pair withclientso filter/payload helpers work without needing the realqdrant_clientpackage installed at all. - tracer (
Tracer | None) – Opens this store's spans.
close
close() -> None
Release the backend connection.
collection_exists
collection_exists(name:str) -> bool
Report whether a collection exists.
Parameters:
- name (
str) – The collection name.
Returns:
bool–Trueif the collection exists.
commit_pending
commit_pending(collection:str, *, job_id:UUID) -> None
Promote one job's staged records to committed records.
Each staged record is written under its real id, which replaces any committed record with that id, and the staged copy is deleted. The method reads the first page of staged records again after each delete, so it needs no offset. Re-running after a failure finishes the remaining records.
Parameters:
- collection (
str) – The collection the job wrote to. - job_id (
UUID) – The committed job whose records become visible.
Raises:
RuntimeError– A delete left the same staged records in place.
count
count(collection:str, *, filters:dict[str, Any] | None = None, pending_job_id:UUID | None = None) -> int
Count records in a collection.
Parameters:
- collection (
str) – The collection to count. - filters (
dict[str, Any] | None) – A flat-dict filter on payload fields. - pending_job_id (
UUID | None) – Count only this job's staged records.
Returns:
int– The number of matching records.
delete
delete(collection:str, ids:Sequence[UUID]) -> None
Delete records by id.
Parameters:
- collection (
str) – The collection to delete from. - ids (
Sequence[UUID]) – The ids to delete.
delete_collection
delete_collection(name:str) -> None
Delete a collection and all its points.
Parameters:
- name (
str) – The collection name.
delete_pending
delete_pending(collection:str, *, job_id:UUID) -> None
Delete one job's staged records, leaving committed records alone.
Parameters:
- collection (
str) – The collection the job wrote to. - job_id (
UUID) – The rolled-back job whose records are deleted.
Raises:
RuntimeError– A delete left the same staged records in place.
ensure_collection
ensure_collection(name:str, *, dimensions:int, distance:Distance, hybrid:bool = False) -> None
Create the collection if it does not exist.
Parameters:
- name (
str) – The collection name. - dimensions (
int) – The embedding dimension. - distance (
Distance) – The distance metric new collections use. - hybrid (
bool) – Whether to provision the named sparse vector hybrid search needs.
Raises:
CollectionDimensionMismatchError– The collection exists with a different dimension thandimensions.VectorStoreError– The collection exists without hybrid search support andhybrid=Truewas requested.
hybrid_search
hybrid_search(collection:str, query_vector:Sequence[float], query_text:str, *, limit:int = 10, filters:dict[str, Any] | None = None, alpha:float = 0.5) -> list[VectorHit]
Search by dense vector and keyword text, fused by a weighted blend.
Qdrant's native fusion methods (RRF, DBSF) have no continuous
dense/keyword weight, so this runs the dense and sparse (BM25)
searches independently, min-max normalizes each result set's scores
to [0, 1], then combines them per id as
alpha * dense + (1 - alpha) * sparse. Each side fetches a wider
candidate pool than limit so a document strong on only one signal
still has a chance to reach the blended top results.
Parameters:
- collection (
str) – The collection to search. - query_vector (
Sequence[float]) – The dense query embedding. - query_text (
str) – The query text, matched by BM25. - limit (
int) – The maximum number of hits to return. - filters (
dict[str, Any] | None) – A flat-dict filter on payload fields. - alpha (
float) – The dense/keyword balance.1.0is pure dense,0.0is pure keyword.
Returns:
list[VectorHit]– The blended hits, highest combined score first.
Raises:
ValueError–limitis not positive, or exceedsMAX_SEARCH_LIMIT, oralphais outside[0.0, 1.0].
initialize
initialize() -> None
Check connectivity and authentication.
invalidate_collection
invalidate_collection(name:str) -> None
Drop cached hybrid-state and distance-metric knowledge of a collection.
This store caches a collection's hybrid support and distance metric
after the first call that resolves them, on the assumption that it
alone (via ensure_collection/delete_collection) owns the
collection's lifecycle for as long as this instance is in use. If
something outside this instance deletes and recreates a collection
under the same name with different config, call this first so the
next call re-resolves that collection's state from the backend
instead of trusting the stale cache.
Parameters:
- name (
str) – The collection name.
retrieve
retrieve(collection:str, ids:Sequence[UUID]) -> list[VectorRecord]
Fetch records by id.
Parameters:
- collection (
str) – The collection to read. - ids (
Sequence[UUID]) – The ids to fetch.
Returns:
list[VectorRecord]– The records that exist, in the requested order, omitting missinglist[VectorRecord]– ids.
scroll
scroll(collection:str, *, limit:int = 100, page_offset:str | None = None, filters:dict[str, Any] | None = None, with_vectors:bool = False, pending_job_id:UUID | None = None) -> tuple[list[VectorRecord], str | None]
Iterate records in a collection, in batches.
Parameters:
- collection (
str) – The collection to read. - limit (
int) – The maximum number of records per page. - page_offset (
str | None) – The offset from a previousscrollcall. - filters (
dict[str, Any] | None) – A flat-dict filter on payload fields. - with_vectors (
bool) – Whether to return each record's vector. - pending_job_id (
UUID | None) – Read only this job's staged records.
Returns:
list[VectorRecord]– The page of records and the next page offset, orNoneat thestr | None– end.
search
search(collection:str, query_vector:Sequence[float], *, limit:int = 10, filters:dict[str, Any] | None = None) -> list[VectorHit]
Search by dense vector only.
Parameters:
- collection (
str) – The collection to search. - query_vector (
Sequence[float]) – The dense query embedding. - limit (
int) – The maximum number of hits to return. - filters (
dict[str, Any] | None) – A flat-dict filter on payload fields.
Returns:
list[VectorHit]– The matched hits, highest score first.
Raises:
ValueError–limitis not positive, or exceedsMAX_SEARCH_LIMIT.
upsert
upsert(collection:str, records:Sequence[VectorRecord], *, batch_size:int = 256, pending_job_id:UUID | None = None) -> None
Write or overwrite records in a collection.
With pending_job_id the records are staged for that job.
When collection has sparse-vector support (created or previously
seen with ensure_collection(..., hybrid=True)), each record's
payload["text"] is also sparse-embedded and stored under the named
sparse vector, so hybrid_search's keyword arm has real vectors to
match. A record with no text payload key gets an empty sparse
vector and only ever surfaces through the dense side of a hybrid
search.
Parameters:
- collection (
str) – The collection to write to. - records (
Sequence[VectorRecord]) – The records to upsert, in order. - batch_size (
int) – The number of records per backend write call. Must be positive. - pending_job_id (
UUID | None) – The in-flight job staging these records.
Raises:
ValueError–batch_sizeis not positive, or a payload uses a key the store reserves for pending records (_pending,_pending_job_id,_target_id).