title: Qdrant description: Production vector database — Qdrant for RAG: collections, payload filtering, hybrid search, cloud deployment, and high-performance vector search. category: 09-RAG tags: [qdrant, vector-store, production, rag, hybrid-search] status: ready last_updated: 2026-09-06
Qdrant¶
Qdrant is a production-ready vector database built in Rust. It offers fast vector search, rich payload filtering, hybrid search (dense + sparse), and easy cloud deployment. Use Qdrant when you need a vector DB that scales beyond local development.
Table of Contents¶
- Installation / Setup
- Core Syntax
- Common Operations
- Practical Examples
- Common Patterns
- Best Practices
- Common Mistakes
- Troubleshooting
- Related Cheat Sheets
- Official Documentation
Installation / Setup¶
Core Syntax¶
Client setup¶
from qdrant_client import QdrantClient
# local (in-memory)
client = QdrantClient(":memory:")
# local (persistent)
client = QdrantClient(path="./qdrant_db")
# cloud
client = QdrantClient(
url="https://xyz.aws.cloud.qdrant.io:6333",
api_key="YOUR_API_KEY",
)
Create collection¶
from qdrant_client.models import Distance, VectorParams
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(
size=1536, # embedding dimension
distance=Distance.COSINE, # COSINE, EUCLID, DOT
),
)
Add points¶
from qdrant_client.models import PointStruct
client.upsert(
collection_name="documents",
points=[
PointStruct(id=1, vector=[0.1]*1536, payload={"source": "doc1", "year": 2024}),
PointStruct(id=2, vector=[0.2]*1536, payload={"source": "doc2", "year": 2025}),
],
)
Search¶
results = client.search(
collection_name="documents",
query_vector=[0.1]*1536,
limit=5,
)
for r in results:
print(f"Score: {r.score:.3f}, Payload: {r.payload}")
LangChain + Qdrant¶
from langchain_community.vectorstores import Qdrant
from langchain_openai import OpenAIEmbeddings
# create from documents
vectorstore = Qdrant.from_documents(
chunks, OpenAIEmbeddings(),
url="https://xyz.aws.cloud.qdrant.io:6333",
api_key="YOUR_API_KEY",
collection_name="documents",
)
# search with filter
docs = vectorstore.similarity_search(
"query", k=5, filter={"source": "report.pdf"}
)
Common Operations¶
Payload filtering¶
from qdrant_client.models import Filter, FieldCondition, MatchValue
# exact match
results = client.search(
collection_name="documents",
query_vector=[0.1]*1536,
query_filter=Filter(must=[
FieldCondition(key="source", match=MatchValue(value="report.pdf"))
]),
limit=5,
)
# range filter
from qdrant_client.models import Range
results = client.search(
collection_name="documents",
query_vector=[0.1]*1536,
query_filter=Filter(must=[
FieldCondition(key="year", range=Range(gte=2024))
]),
limit=5,
)
Collection management¶
# list collections
collections = client.get_collections()
# get collection info
info = client.get_collection("documents")
# delete collection
client.delete_collection("documents")
Incremental updates¶
# upsert (add or update)
client.upsert(
collection_name="documents",
points=[PointStruct(id=new_id, vector=new_vector, payload=new_payload)],
)
# delete
client.delete(
collection_name="documents",
points_selector=[1, 2, 3], # by IDs
)
Practical Examples¶
Example 1 — Qdrant RAG pipeline¶
from qdrant_client import QdrantClient
from langchain_community.vectorstores import Qdrant
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
client = QdrantClient(url="YOUR_URL", api_key="YOUR_KEY")
vectorstore = Qdrant(client, "documents", OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
rag = (
{"context": retriever | (lambda d: "\n\n".join(x.page_content for x in d)),
"question": RunnablePassthrough()}
| ChatPromptTemplate.from_template("Answer:\n{context}\n\nQ: {question}")
| ChatOpenAI(model="gpt-4o")
| StrOutputParser()
)
Common Patterns¶
Pattern: metadata-rich filtering¶
# filter by multiple conditions
from qdrant_client.models import Filter, FieldCondition, MatchValue, Range
filter = Filter(must=[
FieldCondition(key="source", match=MatchValue(value="docs")),
FieldCondition(key="year", range=Range(gte=2024)),
FieldCondition(key="category", match=MatchValue(value="technical")),
])
Best Practices¶
- Use Qdrant Cloud for production — managed, scalable, fast.
- Use COSINE distance for normalized embeddings.
- Add payloads (metadata) for filtering — it's a key advantage.
- Use incremental upserts for updating documents.
- Qdrant supports hybrid search (dense + sparse) — use it for better retrieval.
Common Mistakes¶
| Mistake | Fix |
|---|---|
| Using in-memory for production | Use PersistentClient or Qdrant Cloud |
| Not adding payloads | Payloads enable metadata filtering |
| Wrong distance metric | Use COSINE for most embedding models |
Troubleshooting¶
| Symptom | Cause / Fix |
|---|---|
Connection refused |
Qdrant server not running |
Dimension mismatch |
Vector size doesn't match collection config |
| Slow queries | Add payload index for filtered fields |
Related Cheat Sheets¶
- faiss.md — local alternative
- chroma.md — developer alternative
- pinecone.md — managed alternative
- rag.md — the complete pipeline
Official Documentation¶
- Qdrant docs — https://qdrant.tech/documentation/
- Qdrant Cloud — <https://qdrant.tech/cloud/
Last Updated¶
2026-09-06 — Initial version.