Complete Qdrant Tutorial: Vector Database for AI Applications

# Tutorial Lengkap Qdrant: Vector Database untuk Aplikasi AI Qdrant adalah vector database performa tinggi yang dirancang untuk similarity search dan aplikasi AI. Library ini menyediakan penyimpanan...

By Ruby Abdullah · · tutorial
QdrantVector DatabaseSemantic SearchRAGPythonAI

Complete Qdrant Tutorial: Vector Database for AI Applications

Qdrant is a high-performance vector database designed for similarity search and AI applications. It provides efficient storage and retrieval of vector embeddings, making it ideal for building recommendation systems, semantic search, and RAG applications.

Why Qdrant?

Qdrant Advantages:
  • High performance: Rust-based engine for speed
  • Rich filtering: Combine vector search with metadata filters
  • Scalable: Distributed mode for large datasets
  • Easy to use: REST and gRPC APIs
  • Cloud native: Docker, Kubernetes ready

Use Cases:
  • Semantic search
  • Recommendation systems
  • RAG (Retrieval-Augmented Generation)
  • Image similarity search
  • Anomaly detection

Installation

# Python client

pip install qdrant-client

Run Qdrant with Docker

docker run -p 6333:6333 -p 6334:6334 \

-v $(pwd)/qdrantstorage:/qdrant/storage:z \

qdrant/qdrant

Verify

python -c "from qdrantclient import QdrantClient; print('Qdrant client ready')"

Quick Start

1. Connect to Qdrant

from qdrantclient import QdrantClient

Local instance

client = QdrantClient("localhost", port=6333)

In-memory (for testing)

client = QdrantClient(":memory:")

Qdrant Cloud

client = QdrantClient(

url="https://xxx-xxx.us-east-1-0.aws.cloud.qdrant.io",

apikey="your-api-key"

)

Check connection

print(client.getcollections())

2. Create Collection

from qdrantclient import QdrantClient

from qdrantclient.models import Distance, VectorParams

client = QdrantClient("localhost", port=6333)

Create collection

client.createcollection(

collectionname="mycollection",

vectorsconfig=VectorParams(size=384, distance=Distance.COSINE)

)

List collections

collections = client.getcollections()

print(collections)

3. Insert Vectors

from qdrantclient.models import PointStruct

Insert points

client.upsert(

collectionname="mycollection",

points=[

PointStruct(

id=1,

vector=[0.1, 0.2, 0.3, ...], # 384-dim vector

payload={"title": "Document 1", "category": "tech"}

),

PointStruct(

id=2,

vector=[0.4, 0.5, 0.6, ...],

payload={"title": "Document 2", "category": "science"}

)

]

)

4. Search Vectors

# Search

results = client.search(

collectionname="mycollection",

queryvector=[0.1, 0.2, 0.3, ...],

limit=5

)

for result in results:

print(f"ID: {result.id}, Score: {result.score}")

print(f"Payload: {result.payload}")

Working with Embeddings

1. Using Sentence Transformers

from qdrantclient import QdrantClient

from qdrantclient.models import Distance, VectorParams, PointStruct

from sentencetransformers import SentenceTransformer

Initialize

client = QdrantClient("localhost", port=6333)

model = SentenceTransformer("all-MiniLM-L6-v2")

Create collection

client.recreatecollection(

collectionname="documents",

vectorsconfig=VectorParams(size=384, distance=Distance.COSINE)

)

Prepare documents

documents = [

{"id": 1, "text": "Machine learning is fascinating", "category": "tech"},

{"id": 2, "text": "Natural language processing", "category": "tech"},

{"id": 3, "text": "Cooking recipes for beginners", "category": "food"},

]

Generate embeddings and insert

points = []

for doc in documents:

embedding = model.encode(doc["text"]).tolist()

points.append(PointStruct(

id=doc["id"],

vector=embedding,

payload={"text": doc["text"], "category": doc["category"]}

))

client.upsert(collectionname="documents", points=points)

Search

query = "AI and deep learning"

queryvector = model.encode(query).tolist()

results = client.search(

collectionname="documents",

queryvector=queryvector,

limit=3

)

for result in results:

print(f"Score: {result.score:.4f} - {result.payload['text']}")

2. Using OpenAI Embeddings

from qdrantclient import QdrantClient

from qdrantclient.models import Distance, VectorParams, PointStruct

import openai

client = QdrantClient("localhost", port=6333)

openai.apikey = "your-api-key"

def getembedding(text):

response = openai.embeddings.create(

model="text-embedding-3-small",

input=text

)

return response.data[0].embedding

Create collection (1536 dimensions for text-embedding-3-small)

client.recreatecollection(

collectionname="openaidocs",

vectorsconfig=VectorParams(size=1536, distance=Distance.COSINE)

)

Insert documents

documents = ["Document 1 text", "Document 2 text", "Document 3 text"]

points = []

for i, doc in enumerate(documents):

embedding = getembedding(doc)

points.append(PointStruct(

id=i,

vector=embedding,

payload={"text": doc}

))

client.upsert(collectionname="openaidocs", points=points)

Search

queryembedding = getembedding("Search query")

results = client.search(

collectionname="openaidocs",

queryvector=queryembedding,

limit=5

)

Filtering

1. Basic Filters

from qdrantclient.models import Filter, FieldCondition, MatchValue

Filter by exact match

results = client.search(

collectionname="documents",

queryvector=queryvector,

queryfilter=Filter(

must=[

FieldCondition(

key="category",

match=MatchValue(value="tech")

)

]

),

limit=5

)

2. Complex Filters

from qdrantclient.models import (

Filter, FieldCondition, MatchValue, Range,

MatchAny, MatchExcept

)

Range filter

results = client.search(

collectionname="products",

queryvector=queryvector,

queryfilter=Filter(

must=[

FieldCondition(

key="price",

range=Range(gte=10.0, lte=100.0)

)

]

),

limit=5

)

Match any

results = client.search(

collectionname="documents",

queryvector=queryvector,

queryfilter=Filter(

must=[

FieldCondition(

key="category",

match=MatchAny(any=["tech", "science"])

)

]

),

limit=5

)

Exclude values

results = client.search(

collectionname="documents",

queryvector=queryvector,

queryfilter=Filter(

mustnot=[

FieldCondition(

key="status",

match=MatchValue(value="archived")

)

]

),

limit=5

)

Combined filters (AND/OR)

results = client.search(

collectionname="products",

queryvector=queryvector,

queryfilter=Filter(

must=[

FieldCondition(key="category", match=MatchValue(value="electronics"))

],

should=[

FieldCondition(key="brand", match=MatchValue(value="Apple")),

FieldCondition(key="brand", match=MatchValue(value="Samsung"))

],

mustnot=[

FieldCondition(key="outofstock", match=MatchValue(value=True))

]

),

limit=5

)

3. Nested Filters

from qdrantclient.models import Filter, FieldCondition, MatchValue, NestedCondition

Filter on nested objects

results = client.search(

collectionname="products",

queryvector=queryvector,

queryfilter=Filter(

must=[

FieldCondition(

key="metadata.author",

match=MatchValue(value="John Doe")

)

]

),

limit=5

)

Collection Management

1. Collection Operations

from qdrantclient.models import Distance, VectorParams, OptimizersConfigDiff

Create with optimizer config

client.createcollection(

collectionname="optimizedcollection",

vectorsconfig=VectorParams(size=384, distance=Distance.COSINE),

optimizersconfig=OptimizersConfigDiff(

indexingthreshold=20000,

memmapthreshold=50000

)

)

Get collection info

info = client.getcollection("mycollection")

print(f"Points count: {info.pointscount}")

print(f"Vectors count: {info.vectorscount}")

Update collection

client.updatecollection(

collectionname="mycollection",

optimizersconfig=OptimizersConfigDiff(

indexingthreshold=10000

)

)

Delete collection

client.deletecollection("mycollection")

2. Named Vectors

from qdrantclient.models import VectorParams, Distance

Create collection with multiple vector types

client.createcollection(

collectionname="multivector",

vectorsconfig={

"text": VectorParams(size=384, distance=Distance.COSINE),

"image": VectorParams(size=512, distance=Distance.COSINE)

}

)

Insert with named vectors

client.upsert(

collectionname="multivector",

points=[

PointStruct(

id=1,

vector={

"text": [0.1, 0.2, ...],

"image": [0.3, 0.4, ...]

},

payload={"title": "Product 1"}

)

]

)

Search specific vector

results = client.search(

collectionname="multivector",

queryvector=("text", [0.1, 0.2, ...]),

limit=5

)

Batch Operations

1. Batch Upsert

from qdrantclient.models import PointStruct, Batch

Method 1: List of points

points = [

PointStruct(id=i, vector=vectors[i], payload=payloads[i])

for i in range(len(vectors))

]

client.upsert(collectionname="mycollection", points=points)

Method 2: Batch object (more efficient)

client.upsert(

collectionname="mycollection",

points=Batch(

ids=list(range(len(vectors))),

vectors=vectors,

payloads=payloads

)

)

from qdrantclient.models import SearchRequest

Multiple searches in one request

results = client.searchbatch(

collectionname="mycollection",

requests=[

SearchRequest(vector=queryvector1, limit=5),

SearchRequest(vector=queryvector2, limit=5),

SearchRequest(vector=queryvector3, limit=5)

]

)

for i, result in enumerate(results):

print(f"Query {i}: {len(result)} results")

Payload Management

1. Update Payload

from qdrantclient.models import PointIdsList

Set payload

client.setpayload(

collectionname="mycollection",

payload={"newfield": "newvalue"},

points=[1, 2, 3]

)

Overwrite payload

client.overwritepayload(

collectionname="mycollection",

payload={"completely": "new"},

points=[1]

)

Delete payload keys

client.deletepayload(

collectionname="mycollection",

keys=["oldfield"],

points=[1, 2, 3]

)

2. Payload Indexing

from qdrantclient.models import PayloadSchemaType

Create payload index for faster filtering

client.createpayloadindex(

collectionname="mycollection",

fieldname="category",

fieldschema=PayloadSchemaType.KEYWORD

)

Create index for numeric field

client.createpayloadindex(

collectionname="mycollection",

fieldname="price",

fieldschema=PayloadSchemaType.FLOAT

)

RAG Integration

1. With LangChain

from langchaincommunity.vectorstores import Qdrant

from langchainopenai import OpenAIEmbeddings

from langchain.textsplitter import CharacterTextSplitter

Initialize embeddings

embeddings = OpenAIEmbeddings()

Create vector store

qdrant = Qdrant.fromdocuments(

documents,

embeddings,

url="http://localhost:6333",

collectionname="langchaindocs"

)

Search

results = qdrant.similaritysearch("query text", k=5)

As retriever

retriever = qdrant.asretriever(searchkwargs={"k": 5})

docs = retriever.getrelevantdocuments("query text")

2. With LlamaIndex

from llamaindex.core import VectorStoreIndex, StorageContext

from llamaindex.vectorstores.qdrant import QdrantVectorStore

from qdrantclient import QdrantClient

Initialize Qdrant

client = QdrantClient("localhost", port=6333)

Create vector store

vectorstore = QdrantVectorStore(

client=client,

collectionname="llamaindexdocs"

)

Build index

storagecontext = StorageContext.fromdefaults(vectorstore=vectorstore)

index = VectorStoreIndex.fromdocuments(

documents,

storagecontext=storagecontext

)

Query

queryengine = index.asqueryengine()

response = queryengine.query("What is this about?")

Snapshots and Backup

1. Create Snapshot

# Create snapshot

snapshotinfo = client.createsnapshot(collectionname="mycollection")

print(f"Snapshot created: {snapshotinfo.name}")

List snapshots

snapshots = client.listsnapshots(collectionname="mycollection")

for snapshot in snapshots:

print(f"Snapshot: {snapshot.name}, Size: {snapshot.size}")

2. Recover from Snapshot

# Recover collection from snapshot

client.recoversnapshot(

collectionname="mycollection",

location=f"http://localhost:6333/collections/mycollection/snapshots/{snapshotname}"

)

Or from local file

client.recoversnapshot(

collectionname="mycollection",

location="file:///path/to/snapshot.snapshot"

)

Performance Optimization

1. HNSW Configuration

from qdrantclient.models import HnswConfigDiff

Optimize for recall

client.updatecollection(

collectionname="mycollection",

hnswconfig=HnswConfigDiff(

m=32, # More connections = better recall

efconstruct=200 # Higher = better index quality

)

)

Optimize for speed

client.updatecollection(

collectionname="mycollection",

hnswconfig=HnswConfigDiff(

m=16,

efconstruct=100

)

)

2. Search Parameters

from qdrantclient.models import SearchParams

High precision search

results = client.search(

collectionname="mycollection",

queryvector=queryvector,

searchparams=SearchParams(

hnswef=128, # Higher = more accurate

exact=False

),

limit=10

)

Exact search (slower but precise)

results = client.search(

collectionname="mycollection",

queryvector=queryvector,

searchparams=SearchParams(exact=True),

limit=10

)

Best Practices

1. Efficient Batch Processing

import numpy as np

from tqdm import tqdm

def batchupsert(client, collectionname, vectors, payloads, batchsize=100):

"""Efficient batch upsert with progress bar."""

total = len(vectors)

for i in tqdm(range(0, total, batchsize)):

batchvectors = vectors[i:i+batchsize]

batchpayloads = payloads[i:i+batchsize]

batchids = list(range(i, min(i+batchsize, total)))

points = [

PointStruct(id=id, vector=vec.tolist(), payload=pay)

for id, vec, pay in zip(batchids, batchvectors, batchpayloads)

]

client.upsert(collectionname=collectionname, points=points)

Usage

batchupsert(client, "mycollection", allvectors, allpayloads)

2. Connection Pooling

from qdrantclient import QdrantClient

Use connection pooling for production

client = QdrantClient(

url="http://localhost:6333",

prefergrpc=True, # gRPC is faster for large payloads

timeout=30

)

Conclusion

Qdrant is essential for AI applications with:

  • High performance: Rust-based vector search
  • Rich filtering: Combine semantic and metadata search
  • Scalability: Handle billions of vectors
  • Easy integration: LangChain, LlamaIndex support
  • Production ready: Snapshots, monitoring, cloud
  • Key takeaways:

    • Use appropriate distance metrics for your use case
    • Create payload indexes for filtered searches
    • Batch operations for better performance
    • Configure HNSW parameters based on recall/speed needs
    • Use named vectors for multi-modal applications

    Related Articles

    Complete Pinecone Tutorial: Vector Database for AI and Semantic Search

    Tutorial Lengkap Pinecone: Vector Database untuk AI dan Semantic Search Pinecone adalah managed vector database yang dir...

    Complete LlamaIndex Tutorial: Building RAG Applications with LLMs

    Tutorial Lengkap LlamaIndex: Membangun Aplikasi RAG dengan LLM LlamaIndex adalah framework data yang powerful untuk memb...

    Complete ChromaDB Tutorial: Simple Vector Database for AI

    Tutorial Lengkap ChromaDB: Vector Database Sederhana untuk AI ChromaDB adalah open-source vector database yang dirancang...

    Weaviate: Vector Database with Integrated AI Modules

    Weaviate: Database Vektor dengan AI Modules Terintegrasi Weaviate adalah database vektor open-source yang dirancang untu...