Points

Points are the core entities manipulated by Qdrant. A point is a record composed of a vector and an optional payload.

You can search for points grouped in a collection based on vector similarity. A more detailed description of the process is provided in the Search and Filter section.

This section introduces how to create and manage vectors.

Any modification operation on a point is asynchronous and divided into two steps. In the first stage, the operation will be written to a write-ahead log.

At this moment, even if the machine loses power, the service will not lose data.

Tip: Points are an abstract concept in Qdrant, you can think of them as a row of data in a MySQL table.

Waiting for Results

If the API is called with the &wait=false parameter, or not explicitly specified, the client will receive a confirmation message for data reception:

{
    "result": {
        "operation_id": 123,
        "status": "acknowledged"
    },
    "status": "ok",
    "time": 0.000206061
}

This response does not guarantee immediate retrieval of data. It uses a form of eventual consistency. It may take some time during the actual process of updating the collection. In reality, this request may ultimately fail. If inserting a large number of vectors, we also recommend using asynchronous requests to fully utilize pipeline operations.

If your application logic requires immediate availability for search after the API response, use the ?wait=true flag. In this case, the API will return the result only after the operation is completed:

{
    "result": {
        "operation_id": 0,
        "status": "completed"
    },
    "status": "ok",
    "time": 0.000206061
}

Point ID

Qdrant supports the use of 64-bit unsigned integers and UUIDs as identifiers for points.

Examples of UUID string representations are as follows:

  • Simple representation: 936DA01F9ABD4d9d80C702AF85C822A8
  • Hyphenated representation: 550e8400-e29b-41d4-a716-446655440000
  • URN: urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4

This means that in each request, UUID strings can be used instead of numeric IDs. For example:

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": "5c56c793-69f3-4fbf-87e6-c4bf54c28c26",
            "payload": {"color": "red"},
            "vector": [0.9, 0.1, 0.1]
        }
    ]
}

and

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": 1,
            "payload": {"color": "red"},
            "vector": [0.9, 0.1, 0.1]
        }
    ]
}

are both valid.

Uploading Data Points

To optimize performance, Qdrant supports batch loading of data points. This means that you can load multiple data points into the service in a single API call. Batch loading can significantly reduce network connection overhead.

Qdrant API supports two batch creation methods - record-oriented and column-oriented. Internally, these options are indistinguishable and are simply for convenience in interaction.

Creating data points using the REST API:

PUT /collections/{collection_name}/points

{
    "batch": {
        "ids": [1, 2, 3],
        "payloads": [
            {"color": "red"},
            {"color": "green"},
            {"color": "blue"}
        ],
        "vectors": [
            [0.9, 0.1, 0.1],
            [0.1, 0.9, 0.1],
            [0.1, 0.1, 0.9]
        ]
    }
}

Or use the equivalent method using record-oriented approach:

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": 1,
            "payload": {"color": "red"},
            "vector": [0.9, 0.1, 0.1]
        },
        {
            "id": 2,
            "payload": {"color": "green"},
            "vector": [0.1, 0.9, 0.1]
        },
        {
            "id": 3,
            "payload": {"color": "blue"},
            "vector": [0.1, 0.1, 0.9]
        }
    ]
}

All APIs in Qdrant, including data point loading, are idempotent. This means that performing the same method consecutively is equivalent to a single execution.

In this scenario, this means that when re-uploading data points with the same id, the existing data points will be overwritten.

The idempotent property is useful for using message queues that do not provide precise once-only guarantees. Even in this case, Qdrant ensures data consistency.

Available since v0.10.0

If a collection being created has multiple vectors, you can provide data for each vector by naming the vectors:

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": 1,
            "vector": {
                "image": [0.9, 0.1, 0.1, 0.2],
                "text": [0.4, 0.7, 0.1, 0.8, 0.1, 0.1, 0.9, 0.2]
            }
        },
        {
            "id": 2,
            "vector": {
                "image": [0.2, 0.1, 0.3, 0.9],
                "text": [0.5, 0.2, 0.7, 0.4, 0.7, 0.2, 0.3, 0.9]
            }
        }
    ]
}

Available since v1.2.0

Named vectors are optional. When uploading data points, some vectors may be omitted. For example, you can upload a data point with only the image vector and another with only the text vector.

When modifying a data point with an existing ID, the existing data point is first deleted and then it is re-inserted with the specified vector. In other words, the entire data point will be replaced, and any unspecified vectors will be set to null. If you want to keep existing vectors unchanged and only update specified vectors, please refer to updating vectors.

Modifying Data Points

To modify a data point, you can modify its vector or its payload. There are several methods to achieve this.

Update Vectors

Available from version v1.2.0

This method updates the specified vectors at the given points. The unspecified vectors will remain unchanged. All given points must exist.

REST API (Schema):

PUT /collections/{collection_name}/points/vectors

{
    "points": [
        {
            "id": 1,
            "vector": {
                "image": [0.1, 0.2, 0.3, 0.4]
            }
        },
        {
            "id": 2,
            "vector": {
                "text": [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2]
            }
        }
    ]
}

To update points and replace all vectors, please refer to the upload point operation.

Delete Vectors

Available from version v1.2.0

This method only deletes the specified vectors from the given points. Other vectors will remain unchanged. Points will not be deleted.

REST API (Schema):

POST /collections/{collection_name}/points/vectors/delete

{
    "points": [0, 3, 100],
    "vectors": ["text", "image"]
}

Set Payload

Set the given payload values on points.

REST API (Schema):

POST /collections/{collection_name}/points/payload

{
    "payload": {
        "property1": "string",
        "property2": "string"
    },
    "points": [
        0, 3, 100
    ]
}

You do not need to know the id of the point to be modified. Another way is to use filters.

POST /collections/{collection_name}/points/payload

{
    "payload": {
        "property1": "string",
        "property2": "string"
    },
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    }
}

Overwrite Payload

Completely replace existing payload with the given payload.

REST API (Schema):

PUT /collections/{collection_name}/points/payload

{
    "payload": {
        "property1": "string",
        "property2": "string"
    },
    "points": [
        0, 3, 100
    ]
}

Similar to Set Payload, you do not need to know the id of the point to be modified. Another way is to use filters.

Delete Payload Keys

REST API (Schema):

POST /collections/{collection_name}/points/payload/delete

{
    "keys": ["color", "price"],
    "points": [0, 3, 100]
}

Alternatively, you can use filters to delete payload keys from points.

POST /collections/{collection_name}/points/payload/delete

{
    "keys": ["color", "price"],
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    }
}

Clear Payload

This method removes all payload keys from the specified points.

REST API (Schema):

POST /collections/{collection_name}/points/payload/clear

{
    "points": [0, 3, 100]
}

Delete Points

REST API (Schema):

POST /collections/{collection_name}/points/delete

{
    "points": [0, 3, 100]
}

Another way to specify the points to be deleted is by using a filter:

POST /collections/{collection_name}/points/delete

{
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    }
}

This example deletes all points with { "color": "red" } from the collection.

Retrieve Points

Method to retrieve points by their IDs:

REST API (Schema):

POST /collections/{collection_name}/points

{
    "ids": [0, 3, 100]
}

This method has additional parameters with_vectors and with_payload. Using these parameters, you can select the parts of the points results that you need. Excluding helps to avoid wasting data transfer on useless data.

It is also possible to retrieve a single point via the API:

REST API (Schema):

GET /collections/{collection_name}/points/{point_id}

Scroll

Sometimes it is necessary to retrieve all stored points without knowing their IDs, or to iterate through points that satisfy filtering conditions.

REST API (Schema):

POST /collections/{collection_name}/points/scroll

{
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    },
    "limit": 1,
    "with_payload": true,
    "with_vector": false
}

Returns all points that match color=red:

{
    "result": {
        "next_page_offset": 1,
        "points": [
            {
                "id": 0,
                "payload": {
                    "color": "red"
                }
            }
        ]
    },
    "status": "ok",
    "time": 0.0001
}

The Scroll API will return all points that match the filter in a paginated manner.

All resulting points are sorted by ID. To query the next page, you need to specify the maximum discovered ID in the offset field. For convenience, this ID is also returned in the next_page_offset field. If the value of the next_page_offset field is null, it means the last page has been reached.

Counting Points

Available from version v0.8.4

Sometimes, it is useful to only know how many points match the filtering conditions without actually performing a search.

For example, this can be useful in the following scenarios:

  • Estimating the result size for faceted search
  • Determining the number of pages for pagination
  • Debugging query execution speed

REST API (Schema):

POST /collections/{collection_name}/points/count

{
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    },
    "exact": true
}

Returns the count of points that match the given filtering conditions:

{
    "count": 3811
}

Batch Update

Available since v1.5.0

You can perform batch operations on multiple points. This includes inserting, updating, and deleting points, vectors, and payloads.

A batch update request consists of a series of operations that are executed sequentially. The operations that can be batched include:

  • Insert or update points: upsert or UpsertOperation
  • Delete points: delete_points or DeleteOperation
  • Update vectors: update_vectors or UpdateVectorsOperation
  • Delete vectors: delete_vectors or DeleteVectorsOperation
  • Set payload: set_payload or SetPayloadOperation
  • Overwrite payload: overwrite_payload or OverwritePayload
  • Delete payload: delete_payload or DeletePayloadOperation
  • Clear payload: clear_payload or ClearPayloadOperation

The following example code snippet uses all the operations.

REST API (Schema):

POST /collections/{collection_name}/points/batch

{
    "operations": [
        {
            "upsert": {
                "points": [
                    {
                        "id": 1,
                        "vector": [1.0, 2.0, 3.0, 4.0],
                        "payload": {}
                    }
                ]
            }
        },
        {
            "update_vectors": {
                "points": [
                    {
                        "id": 1,
                        "vector": [1.0, 2.0, 3.0, 4.0]
                    }
                ]
            }
        },
        {
            "delete_vectors": {
                "points": [1],
                "vector": [""]
            }
        },
        {
            "overwrite_payload": {
                "payload": {
                    "test_payload": "1"
                },
                "points": [1]
            }
        },
        {
            "set_payload": {
                "payload": {
                    "test_payload_2": "2",
                    "test_payload_3": "3"
                },
                "points": [1]
            }
        },
        {
            "delete_payload": {
                "keys": ["test_payload_2"],
                "points": [1]
            }
        },
        {
            "clear_payload": {
                "points": [1]
            }
        },
        {"delete": {"points": [1]}}
    ]
}

To use batch points with a single type of operation, use the batch feature directly within that operation.