| name | qdrant |
| description | Qdrant vector database — collections, upsert, search, filtering, payloads, sparse vectors, BM25 |
| triggers | ["qdrant","vector database qdrant","qdrant collection","qdrant search","qdrant upsert","sparse dense hybrid search","qdrant filter","qdrant payload","qdrant python client","vector store qdrant"] |
| do_not_use_for | ["relational queries — use PostgreSQL/SQLite","full-text only — use Elasticsearch","generic key-value store — use Redis"] |
| see_also | ["ragas","langfuse","crawl4ai","firecrawl"] |
Qdrant — Vector Database
Connect + Create Collection
from qdrant_client import QdrantClient
from qdrant_client.models import (
Distance, VectorParams, PointStruct,
Filter, FieldCondition, MatchValue, Range,
SparseVectorParams, SparseIndexParams,
)
client = QdrantClient(":memory:")
client = QdrantClient(path="./qdrant_storage")
client = QdrantClient(
url="http://localhost:6333",
api_key="your-api-key",
timeout=30,
)
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(
size=1536,
distance=Distance.COSINE,
),
)
from qdrant_client.models import NamedVectorStruct
client.create_collection(
collection_name="multi_vec",
vectors_config={
"dense": VectorParams(size=1536, distance=Distance.COSINE),
"sparse": SparseVectorParams(index=SparseIndexParams(on_disk=False)),
},
)
Upsert Points
from qdrant_client.models import PointStruct
client.upsert(
collection_name="documents",
points=[
PointStruct(
id=1,
vector=[0.1, 0.2, ...],
payload={
"text": "Document content",
"source": "wiki",
"year": 2024,
"tags": ["ml", "nlp"],
},
),
PointStruct(id=2, vector=embed("Second doc"), payload={"text": "..."}),
],
wait=True,
)
texts = ["doc1", "doc2", "doc3"]
embeddings = embed_batch(texts)
points = [
PointStruct(id=i, vector=vec, payload={"text": t})
for i, (t, vec) in enumerate(zip(texts, embeddings))
]
client.upsert(collection_name="documents", points=points)
Search
results = client.search(
collection_name="documents",
query_vector=embed("machine learning"),
limit=5,
with_payload=True,
score_threshold=0.7,
)
for r in results:
print(r.score, r.payload["text"])
results = client.search(
collection_name="documents",
query_vector=embed("neural networks"),
query_filter=Filter(
must=[
FieldCondition(key="source", match=MatchValue(value="wiki")),
FieldCondition(key="year", range=Range(gte=2022, lte=2024)),
],
should=[
FieldCondition(key="tags", match=MatchValue(value="ml")),
],
),
limit=10,
with_payload=["text", "source"],
)
Hybrid Search (Dense + Sparse / BM25)
from qdrant_client.models import SparseVector, NamedVector, NamedSparseVector
from fastembed import SparseTextEmbedding
sparse_model = SparseTextEmbedding("prithivida/Splade_PP_en_v1")
def get_sparse(text: str) -> SparseVector:
emb = list(sparse_model.embed([text]))[0]
return SparseVector(indices=emb.indices.tolist(), values=emb.values.tolist())
from qdrant_client.models import Prefetch, FusionQuery, Fusion
results = client.query_points(
collection_name="multi_vec",
prefetch=[
Prefetch(query=embed_dense(query), using="dense", limit=20),
Prefetch(query=get_sparse(query), using="sparse", limit=20),
],
query=FusionQuery(fusion=Fusion.RRF),
limit=5,
with_payload=True,
)
Payload Indexing
from qdrant_client.models import PayloadSchemaType
client.create_payload_index(
collection_name="documents",
field_name="source",
field_schema=PayloadSchemaType.KEYWORD,
)
client.create_payload_index(
collection_name="documents",
field_name="year",
field_schema=PayloadSchemaType.INTEGER,
)
Manage Points
points = client.retrieve(
collection_name="documents",
ids=[1, 2, 3],
with_payload=True,
with_vectors=False,
)
client.delete(
collection_name="documents",
points_selector=Filter(
must=[FieldCondition(key="source", match=MatchValue(value="old"))]
),
)
client.set_payload(
collection_name="documents",
payload={"updated": True},
points=[1, 2],
)
offset = None
while True:
result, offset = client.scroll(
collection_name="documents",
limit=100,
offset=offset,
with_payload=True,
)
if not result:
break
process_batch(result)
Collections Management
colls = client.get_collections()
names = [c.name for c in colls.collections]
info = client.get_collection("documents")
print(info.points_count, info.vectors_count)
client.delete_collection("documents")
client.recreate_collection(
collection_name="documents",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)
Anti-Fake-Pass Checks
- Vector dimension must match
VectorParams(size=...) exactly — mismatches raise Unprocessable
id must be int or UUID string — nested objects raise validation error
score_threshold filters out points — if no results, lower threshold or check embeddings
wait=True on upsert ensures indexing before search — omit only for fire-and-forget ingestion
- Sparse vectors need
SparseVectorParams in collection config — can't add after creation without recreation
query_points (v1.7+) replaces legacy search API — check client version