Quick Start

Installation

The easiest way to use Qdrant is to run a pre-built image. To do this, make sure Docker is installed on your system.

Download image from DockerHub:

docker pull qdrant/qdrant

And run the service inside the docker:

docker run -p 6333:6333 \
    -v $(pwd)/qdrant_storage:/qdrant/storage \
    qdrant/qdrant

In this case Qdrant will use default configuration and store all data under ./qdrant_storage directory.

Now Qdrant should be accessible at localhost:6333

API

All interaction with Qdrant takes place via the REST API.

This example covers the most basic use-case - collection creation and basic vector search. For additional information please refer to the API documentation.

gRPC

In addition to REST API, Qdrant also supports gRPC interface. To enable gPRC interface, specify the following lines in the configuration file:

service:
  grpc_port: 6334

gRPC interface will be available on the specified port. The gRPC methods follow the same principles as REST. For each REST endpoint, there is a corresponding gRPC method. Documentation on all available gRPC methods and structures is available here - gRPC Documentation.

The choice between gRPC and the REST API is a trade-off between convenience and speed. gRPC is a binary protocol and can be more challenging to debug. We recommend switching to it if you are already familiar with Qdrant and are trying to optimize the performance of your application.

If you are applying Qdrant for the first time or working on a prototype, you might prefer to use REST.

Clients

Qdrant provides a set of clients for different programming languages. You can find them here:

  • Python - pip install qdrant-client
  • Rust - cargo add qdrant-client
  • Go - go get github.com/qdrant/go-client

If you are using a language that is not listed here, you can use the REST API directly or generate a client for your language using OpenAPI or protobuf definitions.

Create collection

First - let’s create a collection with dot-production metric.

curl -X PUT 'http://localhost:6333/collections/test_collection' \
    -H 'Content-Type: application/json' \
    --data-raw '{
        "vectors": {
            "size": 4,
            "distance": "Dot"
        }
    }'
from qdrant_client import QdrantClient
from qdrant_client.http.models import Distance, VectorParams

client = QdrantClient("localhost", port=6333)
client.recreate_collection(
    collection_name="test_collection",
    vectors_config=VectorParams(size=4, distance=Distance.DOT),
)

Expected response:

{
    "result": true,
    "status": "ok",
    "time": 0.031095451
}

We can ensure that collection was created:

curl 'http://localhost:6333/collections/test_collection'
collection_info = client.get_collection(collection_name="test_collection")

Expected response:

{
  "result": {
    "status": "green",
    "vectors_count": 0,
    "segments_count": 5,
    "disk_data_size": 0,
    "ram_data_size": 0,
    "config": {
      "params": {
        "vectors": {
          "size": 4,
          "distance": "Dot"
        }
      },
      "hnsw_config": { ... },
      "optimizer_config": { ... },
      "wal_config": { ... }
    }
  },
  "status": "ok",
  "time": 2.1199e-05
}
from qdrant_client.http.models import CollectionStatus

assert collection_info.status == CollectionStatus.GREEN
assert collection_info.vectors_count == 0

Add points

Let’s now add vectors with some payload:

curl -L -X PUT 'http://localhost:6333/collections/test_collection/points?wait=true' \
    -H 'Content-Type: application/json' \
    --data-raw '{
        "points": [
          {"id": 1, "vector": [0.05, 0.61, 0.76, 0.74], "payload": {"city": "Berlin" }},
          {"id": 2, "vector": [0.19, 0.81, 0.75, 0.11], "payload": {"city": ["Berlin", "London"] }},
          {"id": 3, "vector": [0.36, 0.55, 0.47, 0.94], "payload": {"city": ["Berlin", "Moscow"] }},
          {"id": 4, "vector": [0.18, 0.01, 0.85, 0.80], "payload": {"city": ["London", "Moscow"] }},
          {"id": 5, "vector": [0.24, 0.18, 0.22, 0.44], "payload": {"count": [0] }},
          {"id": 6, "vector": [0.35, 0.08, 0.11, 0.44]}
        ]
    }'
from qdrant_client.http.models import PointStruct

operation_info = client.upsert(
    collection_name="test_collection",
    wait=True,
    points=[
        PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
        PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": ["Berlin", "London"]}),
        PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": ["Berlin", "Moscow"]}),
        PointStruct(id=4, vector=[0.18, 0.01, 0.85, 0.80], payload={"city": ["London", "Moscow"]}),
        PointStruct(id=5, vector=[0.24, 0.18, 0.22, 0.44], payload={"count": [0]}),
        PointStruct(id=6, vector=[0.35, 0.08, 0.11, 0.44]),
    ]
)

Expected response:

{
    "result": {
        "operation_id": 0,
        "status": "completed"
    },
    "status": "ok",
    "time": 0.000206061
}
from qdrant_client.http.models import UpdateStatus

assert operation_info.status == UpdateStatus.COMPLETED

Search with filtering

Let’s start with a basic request:

curl -L -X POST 'http://localhost:6333/collections/test_collection/points/search' \
    -H 'Content-Type: application/json' \
    --data-raw '{
        "vector": [0.2,0.1,0.9,0.7],
        "limit": 3
    }'
search_result = client.search(
    collection_name="test_collection",
    query_vector=[0.2, 0.1, 0.9, 0.7], 
    limit=3
)

Expected response:

{
    "result": [
        { "id": 4, "score": 1.362 },
        { "id": 1, "score": 1.273 },
        { "id": 3, "score": 1.208 }
    ],
    "status": "ok",
    "time": 0.000055785
}
assert len(search_result) == 3

print(search_result[0])
# ScoredPoint(id=4, score=1.362, ...)

print(search_result[1])
# ScoredPoint(id=1, score=1.273, ...)

print(search_result[2])
# ScoredPoint(id=3, score=1.208, ...)

But result is different if we add a filter:

curl -L -X POST 'http://localhost:6333/collections/test_collection/points/search' \
    -H 'Content-Type: application/json' \
    --data-raw '{
      "filter": {
          "should": [
              {
                  "key": "city",
                  "match": {
                      "value": "London"
                  }
              }
          ]
      },
      "vector": [0.2, 0.1, 0.9, 0.7],
      "limit": 3
  }'
from qdrant_client.http.models import Filter, FieldCondition, MatchValue


search_result = client.search(
    collection_name="test_collection",
    query_vector=[0.2, 0.1, 0.9, 0.7], 
    query_filter=Filter(
        must=[
            FieldCondition(
                key="city",
                match=MatchValue(value="London")
            )
        ]
    ),
    limit=3
)

Expected response:

{
    "result": [
        { "id": 4, "score": 1.362 },
        { "id": 2, "score": 0.871 }
    ],
    "status": "ok",
    "time": 0.000093972
}
assert len(search_result) == 2

print(search_result[0])
# ScoredPoint(id=4, score=1.362, ...)

print(search_result[1])
# ScoredPoint(id=2, score=0.871, ...)