mirror of
https://github.com/qdrant/qdrant-client.git
synced 2026-09-21 13:37:55 -05:00
Fix TypeError when sorting heterogeneous facet values / mixed-type point ids in local mode (#1377)
* Fix TypeError sorting heterogeneous facet values and mixed-type point ids in local mode facet() broke a count tie with the raw facet value and _search_distance_matrix sorted samples by raw point id; both raise TypeError when the values span types (e.g. int vs str, or int vs UUID id). Route point-id sorting through the existing _universal_id helper, and give facet values a dedicated type-safe key that also keeps equal-count ties deterministic across colliding types (e.g. the string "" and the int 0). Adds regression tests for both. * fix: narrow down the fix to search matrix only --------- Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
This commit is contained in:
committed by
George Panchuk
co-authored by
George Panchuk
parent
69a6ee2299
commit
3ea381504d
@@ -1737,8 +1737,9 @@ class LocalCollection:
|
||||
if len(samples) < 2:
|
||||
return [], []
|
||||
|
||||
# sort samples by id
|
||||
samples = sorted(samples, key=lambda x: x.id)
|
||||
# sort samples by id; use a type-safe key since a collection may mix
|
||||
# integer and UUID (str) point ids, which cannot be compared directly
|
||||
samples = sorted(samples, key=lambda x: self._universal_id(x.id))
|
||||
# extract the ids
|
||||
ids = [sample.id for sample in samples]
|
||||
scores: list[list[ScoredPoint]] = []
|
||||
|
||||
@@ -182,3 +182,39 @@ def test_search_pairs_filter(
|
||||
except AssertionError as e:
|
||||
print(f"\nAttempt {i} failed with filter {query_filter}")
|
||||
raise e
|
||||
|
||||
|
||||
def test_search_matrix_with_mixed_id_types():
|
||||
# Integer and UUID point ids can coexist in one collection. Sampled points are
|
||||
# ordered by id, so local mode has to order the two id types the way the server
|
||||
# does instead of comparing them directly.
|
||||
collection_name = "congruence_search_matrix_mixed_ids"
|
||||
half = TEST_NUM_POINTS // 2
|
||||
points = generate_fixtures(half) + generate_fixtures(half, random_ids=True)
|
||||
|
||||
local_client = init_local()
|
||||
init_client(local_client, points, collection_name=collection_name)
|
||||
|
||||
http_client = init_remote()
|
||||
init_client(http_client, points, collection_name=collection_name)
|
||||
|
||||
grpc_client = init_remote(prefer_grpc=True)
|
||||
|
||||
def search_offsets_mixed_ids(client: QdrantBase) -> models.SearchMatrixOffsetsResponse:
|
||||
return client.search_matrix_offsets(
|
||||
collection_name=collection_name,
|
||||
sample=TEST_NUM_POINTS,
|
||||
limit=3,
|
||||
using="text",
|
||||
)
|
||||
|
||||
def search_pairs_mixed_ids(client: QdrantBase) -> models.SearchMatrixPairsResponse:
|
||||
return client.search_matrix_pairs(
|
||||
collection_name=collection_name,
|
||||
sample=TEST_NUM_POINTS,
|
||||
limit=3,
|
||||
using="text",
|
||||
)
|
||||
|
||||
compare_all_clients_results(local_client, http_client, grpc_client, search_offsets_mixed_ids)
|
||||
compare_all_clients_results(local_client, http_client, grpc_client, search_pairs_mixed_ids)
|
||||
|
||||
Reference in New Issue
Block a user