Files
qdrant/tests/openapi/test_conditional_update.py
Andrey Vasnetsov 9c8ef5574f Update if (#7006)
* implement condition parameter for upsert operation

* fmt

* update api schema

* implement conditional update for update-vectors op

* rename to update_filter for consistency

* add tests

* explicilty ignore strict mode for conditional updates

* rabbit review fix

* Also assert vector element before, confirm we don't normalize

* Simplify filter creation using new helper

* Rename merge_with_ids to with_point_ids

---------

Co-authored-by: timvisee <tim@visee.me>
Co-authored-by: Tim Visée <tim+github@visee.me>
2025-08-26 13:16:18 +02:00

158 lines
4.4 KiB
Python

from operator import itemgetter
import pytest
from .helpers.collection_setup import basic_collection_setup, drop_collection
from .helpers.helpers import request_with_validation
@pytest.fixture(autouse=True)
def setup(on_disk_vectors, on_disk_payload, collection_name):
basic_collection_setup(collection_name=collection_name, on_disk_vectors=on_disk_vectors,
on_disk_payload=on_disk_payload)
yield
drop_collection(collection_name=collection_name)
def test_conditional_update(collection_name):
# Upsert and delete points
response = request_with_validation(
api="/collections/{collection_name}/points/payload",
method="POST",
path_params={"collection_name": collection_name},
body={
"points": [6],
"payload": {
"version": 5
}
},
query_params={"wait": "true"},
)
assert response.ok
# Upsert and delete points
response = request_with_validation(
api="/collections/{collection_name}/points",
method="PUT",
path_params={"collection_name": collection_name},
body={
"points": [
{
"id": 6,
"vector": [1.1, 1.2, 1.3, 1.4],
"payload": {
"version": 4,
"test": "test_value"
}
}
],
"update_filter": {
"must": {
"key": "version",
"range": {
"lt": 4,
}
}
}
},
query_params={"wait": "true"},
)
assert response.ok
# Check that the point was not updated
response = request_with_validation(
api="/collections/{collection_name}/points/{id}",
method="GET",
path_params={
"collection_name": collection_name,
"id": 6
},
query_params={},
)
assert response.ok
assert response.json()["result"]["payload"]["version"] == 5
# Upsert and delete points
response = request_with_validation(
api="/collections/{collection_name}/points",
method="PUT",
path_params={"collection_name": collection_name},
body={
"points": [
{
"id": 6,
"vector": [1.1, 1.2, 1.3, 1.4],
"payload": {
"version": 6,
"test": "test_value"
}
}
],
"update_filter": {
"must": {
"key": "version",
"range": {
"lt": 6,
}
}
}
},
query_params={"wait": "true"},
)
assert response.ok
# Check that the point was not updated
response = request_with_validation(
api="/collections/{collection_name}/points/{id}",
method="GET",
path_params={
"collection_name": collection_name,
"id": 6
},
query_params={},
)
assert response.ok
assert response.json()["result"]["payload"]["version"] == 6
# First vector element must be in expected range, confirms we don't normalize
assert 1.05 < response.json()["result"]["vector"][0] < 1.15
# Upsert and delete points
response = request_with_validation(
api="/collections/{collection_name}/points/vectors",
method="PUT",
path_params={"collection_name": collection_name},
body={
"points": [
{
"id": 6,
"vector": [2.1, 2.2, 2.3, 2.4],
}
],
"update_filter": {
"must": {
"key": "version",
"range": {
"lt": 4,
}
}
}
},
query_params={"wait": "true"},
)
assert response.ok
# Check that the point was not updated
response = request_with_validation(
api="/collections/{collection_name}/points/{id}",
method="GET",
path_params={
"collection_name": collection_name,
"id": 6
},
query_params={},
)
assert response.ok
assert response.json()["result"]["vector"][0] < 2.0