Skip to content

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

pip install qdrant-client               # or: uv add qdrant-client
# cloud: sign up at https://qdrant.tech/cloud/

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}),
    ],
)
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

Official Documentation

Last Updated

2026-09-06 — Initial version.