Qdrant¶
Qdrant is a vector database and similarity search engine that supports rich payload filtering, multiple distance metrics, and both in-memory and persistent storage. This guide uses the qdrant-client v1.16+ API.
What you'll learn¶
- Running Qdrant locally in-memory and with on-disk persistence
- Creating a collection and upserting points with
client.upsert - Querying with
client.query_points - Filtering results by payload fields
- Understanding which legacy methods were removed in v1.9+
Install¶
Running Qdrant server
For a persistent, production-grade setup you can run the official Docker image:
Then connect withQdrantClient(host="localhost", port=6333).
Imports¶
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
Quick start — in-memory collection¶
# ── 1. In-memory client (great for prototyping and tests) ─────────────────────
client = QdrantClient(":memory:")
COLLECTION = "documents"
DIM = 384 # must match your embedding model
# ── 2. Create collection ──────────────────────────────────────────────────────
client.create_collection(
collection_name=COLLECTION,
vectors_config=VectorParams(size=DIM, distance=Distance.COSINE),
)
# ── 3. Sample documents ───────────────────────────────────────────────────────
docs = [
{"id": 1, "text": "The quick brown fox jumps over the lazy dog.", "category": "animals"},
{"id": 2, "text": "A fast auburn fox leaps above a sleepy hound.", "category": "animals"},
{"id": 3, "text": "Quantum computing harnesses superposition.", "category": "science"},
{"id": 4, "text": "Machine learning improves with more data.", "category": "science"},
]
# Simulate embeddings — replace with your real encoder output
import numpy as np
rng = np.random.default_rng(42)
embeddings = rng.standard_normal((len(docs), DIM)).astype("float32")
# ── 4. Upsert points ──────────────────────────────────────────────────────────
client.upsert(
collection_name=COLLECTION,
points=[
PointStruct(
id=doc["id"],
vector=embeddings[i].tolist(),
payload={"text": doc["text"], "category": doc["category"]},
)
for i, doc in enumerate(docs)
],
)
print(client.get_collection(COLLECTION).points_count, "points stored")
Querying with query_points¶
query_vector = rng.standard_normal(DIM).astype("float32").tolist()
results = client.query_points(
collection_name=COLLECTION,
query=query_vector,
limit=2,
)
for point in results.points:
print(f"id={point.id} score={point.score:.4f} text={point.payload['text']}")
query_points returns a QueryResponse object; iterate over .points to access id, score, and payload.
Payload filtering¶
Qdrant lets you combine vector similarity with structured filters on any payload field:
from qdrant_client.models import Filter, FieldCondition, MatchValue
results = client.query_points(
collection_name=COLLECTION,
query=query_vector,
query_filter=Filter(
must=[FieldCondition(key="category", match=MatchValue(value="science"))]
),
limit=5,
)
for point in results.points:
print(point.payload["text"])
Persistent local storage¶
# Vectors are written to disk inside ./qdrant_storage
persistent_client = QdrantClient(path="./qdrant_storage")
persistent_client.create_collection(
collection_name="my_docs",
vectors_config=VectorParams(size=DIM, distance=Distance.DOT),
)
Use QdrantClient(host="localhost", port=6333) to connect to a running Qdrant server instead.
Removed legacy methods — do NOT use
qdrant-client v1.9 removed several methods that appear in older tutorials and blog posts.
These methods no longer exist and calling them raises AttributeError:
client.search(...)— replaced byclient.query_points(...)client.recommend(...)— replaced byclient.query_points(query=RecommendQuery(...))client.discover(...)— replaced byclient.query_points(query=DiscoverQuery(...))- All
*_batchvariants (search_batch,recommend_batch, etc.) — batch via lists insidequery_points
Always use client.upsert(collection_name, points=[...]) and client.query_points(collection_name, query=vector, limit=k).
See Versions and Deprecations for a full migration timeline.
Distance metrics¶
Distance constant |
Use case |
|---|---|
Distance.COSINE |
Sentence embeddings (most common) |
Distance.DOT |
OpenAI text-embedding-3-* (already normalised) |
Distance.EUCLID |
Image / pixel embeddings |
When to use Qdrant¶
Qdrant is a good fit when you need:
- Metadata / payload filtering alongside vector search
- A standalone database process (local Docker or cloud-hosted)
- Production-grade features: snapshots, collections, named vectors, sparse vectors
For a pure in-process option with no server, see FAISS.
Next steps¶
- Review the API change history: Versions and Deprecations
- Compare vector store options: Vector Stores
- In-process alternative: FAISS