Spaces:
Build error
Build error
import pytest | |
from .helpers.collection_setup import basic_collection_setup, drop_collection | |
from .helpers.helpers import request_with_validation | |
def setup(collection_name): | |
basic_collection_setup(collection_name=collection_name) | |
yield | |
drop_collection(collection_name=collection_name) | |
def test_payload_indexing_operations(collection_name): | |
# create payload | |
response = request_with_validation( | |
api='/collections/{collection_name}/points/payload', | |
method="POST", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"payload": {"test_payload": "keyword"}, | |
"points": [6] | |
} | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}', | |
method="GET", | |
path_params={'collection_name': collection_name}, | |
) | |
assert response.ok | |
# Create index | |
response = request_with_validation( | |
api='/collections/{collection_name}/index', | |
method="PUT", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"field_name": "test_payload", | |
"field_schema": "keyword" | |
} | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}', | |
method="GET", | |
path_params={'collection_name': collection_name}, | |
) | |
assert response.ok | |
assert response.json()[ | |
'result']['payload_schema']['test_payload']['data_type'] == "keyword" | |
# Delete index | |
response = request_with_validation( | |
api='/collections/{collection_name}/index/{field_name}', | |
method="DELETE", | |
path_params={'collection_name': collection_name, | |
'field_name': 'test_payload'}, | |
query_params={'wait': 'true'}, | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}', | |
method="GET", | |
path_params={'collection_name': collection_name}, | |
) | |
assert response.ok | |
assert len(response.json()['result']['payload_schema']) == 0 | |
def set_payload(collection_name, payload, points): | |
response = request_with_validation( | |
api='/collections/{collection_name}/points/payload', | |
method="POST", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"payload": payload, | |
"points": points | |
} | |
) | |
assert response.ok | |
def test_index_with_numeric_key(collection_name): | |
response = request_with_validation( | |
api='/collections/{collection_name}/index', | |
method="PUT", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"field_name": "123", | |
"field_schema": "keyword" | |
} | |
) | |
assert response.ok | |
def test_boolean_index(collection_name): | |
bool_key = "boolean_payload" | |
# create payload | |
set_payload(collection_name, {bool_key: False}, [1, 2, 3, 4]) | |
set_payload(collection_name, {bool_key: [True, False]}, [5]) | |
set_payload(collection_name, {bool_key: True}, [6, 7]) | |
# Create index | |
response = request_with_validation( | |
api='/collections/{collection_name}/index', | |
method="PUT", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"field_name": bool_key, | |
"field_schema": "bool" | |
} | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}', | |
method="GET", | |
path_params={'collection_name': collection_name}, | |
) | |
assert response.ok | |
assert response.json()[ | |
'result']['payload_schema'][bool_key]['data_type'] == "bool" | |
assert response.json()['result']['payload_schema'][bool_key]['points'] == 7 | |
# Delete index | |
response = request_with_validation( | |
api='/collections/{collection_name}/index/{field_name}', | |
method="DELETE", | |
path_params={'collection_name': collection_name, | |
'field_name': bool_key}, | |
query_params={'wait': 'true'}, | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}', | |
method="GET", | |
path_params={'collection_name': collection_name}, | |
) | |
assert response.ok | |
assert len(response.json()['result']['payload_schema']) == 0 | |
def test_datetime_indexing(collection_name): | |
datetime_key = "datetime_payload" | |
# create payload | |
set_payload(collection_name, {datetime_key: "2015-01-01T00:00:00Z"}, [1]) | |
set_payload(collection_name, {datetime_key: "2015-02-01T08:00:00+02:00"}, [2]) | |
# Create index | |
response = request_with_validation( | |
api='/collections/{collection_name}/index', | |
method="PUT", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"field_name": datetime_key, | |
"field_schema": "datetime" | |
} | |
) | |
assert response.ok | |
# test with mixed datetime format | |
data = [ | |
({"gte": "2015-01-01", "lte": "2015-01-01 00:00"}, [1]), | |
({"gte": "2015-01-01T01:00:00+01:00", "lte": "2015-01-01T01:00:00+01:00"}, [1]), | |
({"gte": "2015-02-01T06:00:00", "lte": "2015-02-01T06:00:00Z"}, [2]), | |
# date_optional_time | |
({"gte": "2015-02-01T06:00:00.000000000", "lte": "2015-02-01T06:00:00.000000000"}, [2]), | |
] | |
for range_, expected_ids in data: | |
response = request_with_validation( | |
api="/collections/{collection_name}/points/scroll", | |
method="POST", | |
path_params={"collection_name": collection_name}, | |
body={ | |
"with_vector": False, | |
"filter": {"must": [{"key": datetime_key, "range": range_}]}, | |
}, | |
) | |
assert response.ok, response.json() | |
point_ids = [p["id"] for p in response.json()["result"]["points"]] | |
assert all(id in point_ids for id in expected_ids) | |
# test with wrong/unsupported datetime format | |
wrong_data = [ | |
# RFC 2822 format | |
({"gte": "Thu, 01 Jan 2015 01:00:00 +0100", | |
"lte": "Thu, 01 Jan 2015 01:00:00 +0100"}, [1]), | |
# Unix millisecond timestamp | |
({"gte": "1422758400000", "lte": "1422758400000"}, [1]), | |
# Unix second timestamp | |
({"gte": "1420070400", "lte": "1420070400"}, [1]), | |
# Human readable format | |
({"gte": "2015-02-01 06:00:00 AM", | |
"lte": "2015-02-01 06:00:00 AM"}, [2]), | |
# Here are some elasticsearch built-in datetime format | |
# Reference: https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html#built-in-date-formats | |
# basic_date | |
({"gte": "20150201", "lte": "20150201"}, [2]), | |
# basic_date_time | |
({"gte": "20150201T060000.000Z", "lte": "20150201T060000.000Z"}, [2]), | |
# basic_ordinal_date_time_no_millis | |
({"gte": "2015032T060000Z", "lte": "2015032T060000Z"}, [2]), | |
# wrong format mixed with supported format | |
({"gte": "2015032T060000Z", "lte": "2015-02-01T06:00:00"}, [2]), | |
] | |
for range_, expected_ids in wrong_data: | |
response = request_with_validation( | |
api="/collections/{collection_name}/points/scroll", | |
method="POST", | |
path_params={"collection_name": collection_name}, | |
body={ | |
"with_vector": False, | |
"filter": {"must": [{"key": datetime_key, "range": range_}]}, | |
}, | |
) | |
assert not response.ok | |
def test_update_payload_on_indexed_field(collection_name): | |
keyword_field = "city" | |
response = request_with_validation( | |
api='/collections/{collection_name}/index', | |
method="PUT", | |
path_params={'collection_name': collection_name}, | |
query_params={'wait': 'true'}, | |
body={ | |
"field_name": keyword_field, | |
"field_schema": "keyword" | |
} | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}', | |
method="PATCH", | |
path_params={'collection_name': collection_name}, | |
body={ | |
"optimizers_config": { | |
"indexing_threshold": 100 | |
} | |
} | |
) | |
assert response.ok | |
response = request_with_validation( | |
api='/collections/{collection_name}/points/scroll', | |
method="POST", | |
path_params={'collection_name': collection_name}, | |
body={ | |
"with_vector": False, | |
"filter": { | |
"must": [ | |
{"key": "city", "match": {"value": "Berlin"}} | |
] | |
} | |
} | |
) | |
assert response.ok | |
assert [p['id'] for p in response.json()['result']['points']] == [1, 2, 3] | |
# 2: city: [Berlin, London] | |
# 4: city: [London, Moscow] | |
set_payload(collection_name, {"foo": "bar"}, [2, 4]) | |
response = request_with_validation( | |
api='/collections/{collection_name}/points/scroll', | |
method="POST", | |
path_params={'collection_name': collection_name}, | |
body={ | |
"with_vector": False, | |
"filter": { | |
"must": [ | |
{"key": "city", "match": {"value": "Berlin"}} | |
] | |
} | |
} | |
) | |
assert response.ok | |
assert [p['id'] for p in response.json()['result']['points']] == [1, 2, 3] | |
def test_payload_schemas(collection_name): | |
FIELDS = [ | |
"keyword", | |
"integer", | |
"float", | |
"geo", | |
"text", | |
"bool", | |
"datetime", | |
"uuid", | |
{ | |
"type": "keyword", | |
"is_tenant": True, | |
"on_disk": True, | |
}, | |
{ | |
"type": "integer", | |
"lookup": True, | |
"range": True, | |
"is_principal": True, | |
"on_disk": True, | |
}, | |
{ | |
"type": "float", | |
"on_disk": True, | |
"is_principal": True, | |
}, | |
{ | |
"type": "geo", | |
}, | |
{ | |
"type": "text", | |
"tokenizer": "word", | |
"lowercase": True, | |
"min_token_len": 2, | |
"max_token_len": 10, | |
}, | |
{ | |
"type": "bool", | |
}, | |
{ | |
"type": "datetime", | |
"on_disk": True, | |
"is_principal": True, | |
}, | |
{ | |
"type": "uuid", | |
"is_tenant": True, | |
"on_disk": True, | |
}, | |
] | |
try: | |
for field_no, schema in enumerate(FIELDS): | |
response = request_with_validation( | |
api="/collections/{collection_name}/index", | |
method="PUT", | |
path_params={"collection_name": collection_name}, | |
query_params={"wait": "true"}, | |
body={ | |
"field_name": f"field_{field_no:02d}", | |
"field_schema": schema, | |
}, | |
) | |
assert response.ok | |
response = request_with_validation( | |
api="/collections/{collection_name}", | |
method="GET", | |
path_params={"collection_name": collection_name}, | |
) | |
assert response.ok | |
for field_no, schema in enumerate(FIELDS): | |
actual_schema = response.json()["result"]["payload_schema"][ | |
f"field_{field_no:02d}" | |
] | |
if isinstance(schema, str): | |
assert actual_schema["data_type"] == schema | |
assert "params" not in actual_schema | |
else: | |
assert actual_schema["data_type"] == schema["type"] | |
assert actual_schema["params"] == schema | |
assert actual_schema["points"] == 0 | |
finally: | |
for field_no in range(len(FIELDS)): | |
response = request_with_validation( | |
api="/collections/{collection_name}/index/{field_name}", | |
method="DELETE", | |
path_params={ | |
"collection_name": collection_name, | |
"field_name": f"field_{field_no:02d}", | |
}, | |
) | |