Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/qdrant/qdrant/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Points service provides gRPC methods for all vector operations including CRUD, search, recommendations, and advanced queries.

Service Definition

From points_service.proto:8-103:
service Points {
  rpc Upsert(UpsertPoints) returns (PointsOperationResponse);
  rpc Delete(DeletePoints) returns (PointsOperationResponse);
  rpc Get(GetPoints) returns (GetResponse);
  rpc UpdateVectors(UpdatePointVectors) returns (PointsOperationResponse);
  rpc DeleteVectors(DeletePointVectors) returns (PointsOperationResponse);
  rpc SetPayload(SetPayloadPoints) returns (PointsOperationResponse);
  rpc OverwritePayload(SetPayloadPoints) returns (PointsOperationResponse);
  rpc DeletePayload(DeletePayloadPoints) returns (PointsOperationResponse);
  rpc ClearPayload(ClearPayloadPoints) returns (PointsOperationResponse);
  rpc CreateFieldIndex(CreateFieldIndexCollection) returns (PointsOperationResponse);
  rpc DeleteFieldIndex(DeleteFieldIndexCollection) returns (PointsOperationResponse);
  rpc Search(SearchPoints) returns (SearchResponse);
  rpc SearchBatch(SearchBatchPoints) returns (SearchBatchResponse);
  rpc SearchGroups(SearchPointGroups) returns (SearchGroupsResponse);
  rpc Scroll(ScrollPoints) returns (ScrollResponse);
  rpc Recommend(RecommendPoints) returns (RecommendResponse);
  rpc RecommendBatch(RecommendBatchPoints) returns (RecommendBatchResponse);
  rpc RecommendGroups(RecommendPointGroups) returns (RecommendGroupsResponse);
  rpc Discover(DiscoverPoints) returns (DiscoverResponse);
  rpc DiscoverBatch(DiscoverBatchPoints) returns (DiscoverBatchResponse);
  rpc Count(CountPoints) returns (CountResponse);
  rpc UpdateBatch(UpdateBatchPoints) returns (UpdateBatchResponse);
  rpc Query(QueryPoints) returns (QueryResponse);
  rpc QueryBatch(QueryBatchPoints) returns (QueryBatchResponse);
  rpc QueryGroups(QueryPointGroups) returns (QueryGroupsResponse);
  rpc Facet(FacetCounts) returns (FacetResponse);
}

Upsert Points

Insert or update points with vectors and payload:

Python Example

from qdrant_client import QdrantClient, models

client = QdrantClient("localhost", grpc_port=6334, prefer_grpc=True)

client.upsert(
    collection_name="my_collection",
    points=[
        models.PointStruct(
            id=1,
            vector=[0.1, 0.2, 0.3, 0.4],
            payload={
                "title": "Document 1",
                "category": "technology",
                "views": 1500
            }
        ),
        models.PointStruct(
            id=2,
            vector=[0.2, 0.3, 0.4, 0.5],
            payload={
                "title": "Document 2",
                "category": "science",
                "views": 2300
            }
        )
    ],
    wait=True  # Wait for operation to complete
)

Batch Upsert (High Performance)

import numpy as np
from qdrant_client import models

# Generate 10000 random vectors
vectors = np.random.rand(10000, 384).tolist()

# Batch upsert with optimized settings
client.upload_points(
    collection_name="my_collection",
    points=[
        models.PointStruct(
            id=idx,
            vector=vector,
            payload={"index": idx}
        )
        for idx, vector in enumerate(vectors)
    ],
    batch_size=100,  # Upload in batches of 100
    parallel=4,  # Use 4 parallel workers
    wait=False  # Async mode for better throughput
)

Named Vectors

from qdrant_client import models

client.upsert(
    collection_name="multi_vector",
    points=[
        models.PointStruct(
            id=1,
            vector={
                "text": [0.1, 0.2, 0.3],
                "image": [0.4, 0.5, 0.6]
            },
            payload={"type": "multimodal"}
        )
    ]
)
Find nearest neighbors using vector similarity:
results = client.search(
    collection_name="my_collection",
    query_vector=[0.1, 0.2, 0.3, 0.4],
    limit=10,
    with_payload=True,
    with_vectors=False
)

for result in results:
    print(f"ID: {result.id}, Score: {result.score}")
    print(f"Payload: {result.payload}")

Search with Filters

from qdrant_client import models

results = client.search(
    collection_name="my_collection",
    query_vector=[0.1, 0.2, 0.3, 0.4],
    query_filter=models.Filter(
        must=[
            models.FieldCondition(
                key="category",
                match=models.MatchValue(value="technology")
            ),
            models.FieldCondition(
                key="views",
                range=models.Range(gte=1000)
            )
        ]
    ),
    limit=5,
    score_threshold=0.7  # Only return results with score > 0.7
)

Search Parameters

from qdrant_client import models

results = client.search(
    collection_name="my_collection",
    query_vector=[0.1, 0.2, 0.3, 0.4],
    limit=20,
    search_params=models.SearchParams(
        hnsw_ef=128,  # Higher ef = better recall, slower search
        exact=False,  # Use approximate search (HNSW)
        quantization=models.QuantizationSearchParams(
            ignore=False,
            rescore=True,  # Rescore top-k with original vectors
            oversampling=2.0  # Fetch 2x more candidates before rescoring
        )
    )
)
from qdrant_client import models

search_queries = [
    models.SearchRequest(
        vector=[0.1, 0.2, 0.3],
        limit=5,
        filter=models.Filter(
            must=[models.FieldCondition(key="category", match=models.MatchValue(value="tech"))]
        )
    ),
    models.SearchRequest(
        vector=[0.4, 0.5, 0.6],
        limit=10
    )
]

results = client.search_batch(
    collection_name="my_collection",
    requests=search_queries
)

Recommend

Find similar points based on positive and negative examples:
from qdrant_client import models

# Recommend points similar to point 1, but not like point 10
results = client.recommend(
    collection_name="my_collection",
    positive=[1, 5, 7],  # Points to use as positive examples
    negative=[10, 15],   # Points to avoid
    limit=10,
    strategy=models.RecommendStrategy.BEST_SCORE
)

Recommend with Vectors

results = client.recommend(
    collection_name="my_collection",
    positive=[
        models.RecommendExample(id=1),
        models.RecommendExample(vector=[0.1, 0.2, 0.3])
    ],
    negative=[
        models.RecommendExample(vector=[0.9, 0.8, 0.7])
    ],
    limit=10
)

Query API (Universal)

The Query API unifies search, recommend, discover, and more:
from qdrant_client import models

results = client.query_points(
    collection_name="my_collection",
    query=[0.1, 0.2, 0.3, 0.4],
    limit=10
)

Recommendation Query

results = client.query_points(
    collection_name="my_collection",
    query=models.RecommendQuery(
        recommend=models.RecommendInput(
            positive=[1, 2, 3],
            negative=[10]
        )
    ),
    limit=10
)

Hybrid Search (Fusion)

from qdrant_client import models

results = client.query_points(
    collection_name="my_collection",
    prefetch=[
        models.Prefetch(
            query=[0.1, 0.2, 0.3],  # Dense vector search
            using="dense",
            limit=100
        ),
        models.Prefetch(
            query=models.SparseVector(
                indices=[1, 5, 10],
                values=[0.5, 0.3, 0.2]
            ),  # Sparse vector (BM25-like)
            using="sparse",
            limit=100
        )
    ],
    query=models.FusionQuery(fusion=models.Fusion.RRF),  # Reciprocal Rank Fusion
    limit=10
)

Get Points

Retrieve points by ID:
points = client.retrieve(
    collection_name="my_collection",
    ids=[1, 2, 3, 10, 20],
    with_payload=True,
    with_vectors=True
)

for point in points:
    print(f"ID: {point.id}")
    print(f"Vector: {point.vector}")
    print(f"Payload: {point.payload}")

Scroll

Iterate through all points:
from qdrant_client import models

# Scroll through all points
offset = None
all_points = []

while True:
    result = client.scroll(
        collection_name="my_collection",
        limit=100,
        offset=offset,
        with_payload=True,
        with_vectors=False
    )
    
    all_points.extend(result[0])
    offset = result[1]  # Next page offset
    
    if offset is None:
        break

print(f"Total points: {len(all_points)}")

Scroll with Filter

from qdrant_client import models

result = client.scroll(
    collection_name="my_collection",
    scroll_filter=models.Filter(
        must=[
            models.FieldCondition(
                key="category",
                match=models.MatchValue(value="science")
            )
        ]
    ),
    limit=50
)

Update Operations

Update Vectors

from qdrant_client import models

client.update_vectors(
    collection_name="my_collection",
    points=[
        models.PointVectors(
            id=1,
            vector=[0.9, 0.8, 0.7, 0.6]
        )
    ]
)

Set Payload

from qdrant_client import models

client.set_payload(
    collection_name="my_collection",
    payload={
        "updated": True,
        "timestamp": "2024-01-01"
    },
    points=[1, 2, 3]  # Update these point IDs
)

Overwrite Payload

from qdrant_client import models

# Replace entire payload
client.overwrite_payload(
    collection_name="my_collection",
    payload={"new_field": "value"},
    points=[1, 2]
)

Delete Payload Keys

client.delete_payload(
    collection_name="my_collection",
    keys=["old_field", "deprecated_field"],
    points=[1, 2, 3]
)

Clear Payload

from qdrant_client import models

# Remove all payload from points
client.clear_payload(
    collection_name="my_collection",
    points_selector=models.PointIdsList(points=[1, 2, 3])
)

Delete Points

Delete by IDs

from qdrant_client import models

client.delete(
    collection_name="my_collection",
    points_selector=models.PointIdsList(
        points=[1, 2, 3, 100, 200]
    )
)

Delete by Filter

from qdrant_client import models

client.delete(
    collection_name="my_collection",
    points_selector=models.FilterSelector(
        filter=models.Filter(
            must=[
                models.FieldCondition(
                    key="category",
                    match=models.MatchValue(value="outdated")
                )
            ]
        )
    )
)

Payload Indexing

Create indexes for faster filtering:
from qdrant_client import models

# Create keyword index
client.create_payload_index(
    collection_name="my_collection",
    field_name="category",
    field_schema=models.PayloadSchemaType.KEYWORD
)

# Create integer index with range support
client.create_payload_index(
    collection_name="my_collection",
    field_name="views",
    field_schema=models.PayloadSchemaType.INTEGER
)

# Create geo index
client.create_payload_index(
    collection_name="my_collection",
    field_name="location",
    field_schema=models.PayloadSchemaType.GEO
)

# Create text index for full-text search
client.create_payload_index(
    collection_name="my_collection",
    field_name="description",
    field_schema=models.PayloadSchemaType.TEXT,
    field_index_params=models.TextIndexParams(
        type="text",
        tokenizer=models.TokenizerType.WORD,
        lowercase=True,
        min_token_len=2,
        max_token_len=20
    )
)

Count Points

from qdrant_client import models

# Count all points
count = client.count(
    collection_name="my_collection",
    exact=True
)
print(f"Total points: {count.count}")

# Count with filter
count = client.count(
    collection_name="my_collection",
    count_filter=models.Filter(
        must=[
            models.FieldCondition(
                key="category",
                match=models.MatchValue(value="technology")
            )
        ]
    ),
    exact=True
)
print(f"Technology points: {count.count}")

Facet Counts

Get value distribution for a field:
from qdrant_client import models

facets = client.facet(
    collection_name="my_collection",
    key="category",
    limit=10
)

for facet in facets:
    print(f"{facet.value}: {facet.count}")

Consistency & Ordering

Write Consistency

From points.proto:11-20:
enum WriteOrderingType {
  Weak = 0;    // Reordered, fastest
  Medium = 1;  // Dynamic leader, may be inconsistent briefly
  Strong = 2;  // Permanent leader, consistent
}
from qdrant_client import models

client.upsert(
    collection_name="my_collection",
    points=[models.PointStruct(id=1, vector=[0.1, 0.2, 0.3])],
    ordering=models.WriteOrdering.STRONG  # Strongest consistency
)

Read Consistency

from qdrant_client import models

results = client.search(
    collection_name="my_collection",
    query_vector=[0.1, 0.2, 0.3],
    limit=10,
    consistency=models.ReadConsistency.QUORUM  # Read from majority
)

Shard Key Selection

For custom-sharded collections:
from qdrant_client import models

# Upsert to specific shard
client.upsert(
    collection_name="tenant_sharded",
    points=[models.PointStruct(id=1, vector=[0.1, 0.2, 0.3])],
    shard_key_selector=["tenant_a"]
)

# Search in specific shard
results = client.search(
    collection_name="tenant_sharded",
    query_vector=[0.1, 0.2, 0.3],
    limit=10,
    shard_key_selector=["tenant_a"]
)

Batch Operations

Perform multiple operations in a single request:
from qdrant_client import models

results = client.batch_update_points(
    collection_name="my_collection",
    update_operations=[
        models.UpsertOperation(
            upsert=models.PointsList(
                points=[
                    models.PointStruct(id=1, vector=[0.1, 0.2, 0.3])
                ]
            )
        ),
        models.SetPayloadOperation(
            set_payload=models.SetPayload(
                payload={"status": "active"},
                points=[2, 3, 4]
            )
        ),
        models.DeleteOperation(
            delete=models.PointIdsList(points=[100, 101])
        )
    ]
)

Performance Tips

Optimize throughput:
  • Use batch operations for bulk inserts (100-1000 points per batch)
  • Set wait=False for async mode (10x faster)
  • Use parallel uploads with upload_points() method
  • Enable gRPC with prefer_grpc=True for 30-50% speedup
Search performance:
  • Create payload indexes before filtering on fields
  • Use score_threshold to reduce result processing
  • Lower hnsw_ef for faster search (trade-off with recall)
  • Consider quantization for large collections (>1M vectors)

Next Steps

Collections

Collection management API

Python Client

Full Python client reference