qdrant-haystack 10.6.0__tar.gz → 11.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/CHANGELOG.md +40 -19
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/PKG-INFO +1 -1
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/qdrant/document_store.py +101 -90
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_document_store.py +14 -9
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_document_store_async.py +14 -9
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/.gitignore +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/LICENSE.txt +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/README.md +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/examples/embedding_retrieval.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/pydoc/config_docusaurus.yml +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/pyproject.toml +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/components/retrievers/py.typed +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/components/retrievers/qdrant/__init__.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/components/retrievers/qdrant/retriever.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/py.typed +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/qdrant/__init__.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/qdrant/converters.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/qdrant/filters.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/qdrant/migrate_to_sparse.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/__init__.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/conftest.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_converters.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_dict_converters.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_embedding_retriever.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_filters.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_hybrid_retriever.py +0 -0
- {qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/tests/test_sparse_embedding_retriever.py +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [integrations/qdrant-v10.6.0] - 2026-09-01
|
|
4
|
+
|
|
5
|
+
### 🐛 Bug Fixes
|
|
6
|
+
|
|
7
|
+
- Standardize license files (#3771)
|
|
8
|
+
- `QdrantDocumentStore` removing duplicated tests already covered by haystack Mixin tests + fixing dedup + adding missing Async test (#3785)
|
|
9
|
+
|
|
10
|
+
|
|
3
11
|
## [integrations/qdrant-v10.5.0] - 2026-08-03
|
|
4
12
|
|
|
5
13
|
### 🚀 Features
|
|
@@ -79,7 +87,7 @@
|
|
|
79
87
|
|
|
80
88
|
- Feat: `QdrantDocumentStore` return number deleted docs on `delete_by_filter` (#2807)
|
|
81
89
|
|
|
82
|
-
## [integrations/qdrant-
|
|
90
|
+
## [integrations/qdrant-v10.1.0] - 2026-02-02
|
|
83
91
|
|
|
84
92
|
### 🚀 Features
|
|
85
93
|
|
|
@@ -87,11 +95,15 @@
|
|
|
87
95
|
|
|
88
96
|
### 🧹 Chores
|
|
89
97
|
|
|
90
|
-
- Make fmt command more forgiving (#2671)
|
|
91
|
-
- [**breaking**] Qdrant - drop Python 3.9 and use X|Y typing (#2726)
|
|
92
98
|
- Disabling progress bar in `QdrantDocumentStore` tests (#2797)
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
|
|
101
|
+
## [integrations/qdrant-v10.0.0] - 2026-01-13
|
|
102
|
+
|
|
103
|
+
### 🧹 Chores
|
|
104
|
+
|
|
105
|
+
- Make fmt command more forgiving (#2671)
|
|
106
|
+
- [**breaking**] Qdrant - drop Python 3.9 and use X|Y typing (#2726)
|
|
95
107
|
|
|
96
108
|
|
|
97
109
|
## [integrations/qdrant-v9.5.0] - 2026-01-07
|
|
@@ -151,6 +163,8 @@
|
|
|
151
163
|
- Align core-integrations Hatch scripts (#1898)
|
|
152
164
|
- Update md files for new hatch scripts (#1911)
|
|
153
165
|
|
|
166
|
+
## [integrations/qdrant-v9.1.3] - 2025-05-28
|
|
167
|
+
|
|
154
168
|
### 🌀 Miscellaneous
|
|
155
169
|
|
|
156
170
|
- Add pins for Qdrant (#1853)
|
|
@@ -374,6 +388,18 @@
|
|
|
374
388
|
- *(Qdrant)* Allow payload indexing + on disk vectors (#553)
|
|
375
389
|
- Qdrant datetime filtering support (#570)
|
|
376
390
|
|
|
391
|
+
### 📚 Documentation
|
|
392
|
+
|
|
393
|
+
- Disable-class-def (#556)
|
|
394
|
+
|
|
395
|
+
### 🌀 Miscellaneous
|
|
396
|
+
|
|
397
|
+
- Make tests show coverage (#566)
|
|
398
|
+
- Remove references to Python 3.7 (#601)
|
|
399
|
+
- Make Document Stores initially skip `SparseEmbedding` (#606)
|
|
400
|
+
|
|
401
|
+
## [integrations/qdrant-v3.1.0] - 2024-03-06
|
|
402
|
+
|
|
377
403
|
### 🐛 Bug Fixes
|
|
378
404
|
|
|
379
405
|
- Fix: fix linter errors (#282)
|
|
@@ -388,18 +414,11 @@
|
|
|
388
414
|
|
|
389
415
|
- Update category slug (#442)
|
|
390
416
|
- Small consistency improvements (#536)
|
|
391
|
-
- Disable-class-def (#556)
|
|
392
417
|
|
|
393
418
|
### ⚙️ CI
|
|
394
419
|
|
|
395
420
|
- Generate API docs for Qdrant (#361)
|
|
396
421
|
|
|
397
|
-
### 🌀 Miscellaneous
|
|
398
|
-
|
|
399
|
-
- Make tests show coverage (#566)
|
|
400
|
-
- Remove references to Python 3.7 (#601)
|
|
401
|
-
- Make Document Stores initially skip `SparseEmbedding` (#606)
|
|
402
|
-
|
|
403
422
|
## [integrations/qdrant-v3.0.0] - 2024-01-22
|
|
404
423
|
|
|
405
424
|
### 🌀 Miscellaneous
|
|
@@ -408,20 +427,22 @@
|
|
|
408
427
|
|
|
409
428
|
## [integrations/qdrant-v2.0.1] - 2024-01-18
|
|
410
429
|
|
|
411
|
-
### 🚀 Features
|
|
412
|
-
|
|
413
|
-
- Add Qdrant integration (#98)
|
|
414
|
-
|
|
415
430
|
### 🐛 Bug Fixes
|
|
416
431
|
|
|
417
432
|
- Fix import paths for beta5 (#237)
|
|
418
433
|
|
|
419
|
-
### 🚜 Refactor
|
|
420
|
-
|
|
421
|
-
- Use `hatch_vcs` to manage integrations versioning (#103)
|
|
422
|
-
|
|
423
434
|
### 🌀 Miscellaneous
|
|
424
435
|
|
|
425
436
|
- Renamed QdrntRetriever to QdrntEmbeddingRetriever (#174)
|
|
426
437
|
|
|
438
|
+
## [integrations/qdrant-v2.0.0] - 2023-12-18
|
|
439
|
+
|
|
440
|
+
### 🚀 Features
|
|
441
|
+
|
|
442
|
+
- Add Qdrant integration (#98)
|
|
443
|
+
|
|
444
|
+
### 🚜 Refactor
|
|
445
|
+
|
|
446
|
+
- Use `hatch_vcs` to manage integrations versioning (#103)
|
|
447
|
+
|
|
427
448
|
<!-- generated by git-cliff -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: qdrant-haystack
|
|
3
|
-
Version:
|
|
3
|
+
Version: 11.0.0
|
|
4
4
|
Summary: An integration of Qdrant ANN vector database backend with Haystack
|
|
5
5
|
Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations
|
|
6
6
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/qdrant/README.md
|
|
@@ -15,7 +15,6 @@ from haystack.utils import Secret, deserialize_secrets_inplace
|
|
|
15
15
|
from haystack.utils.misc import _normalize_metadata_field_name
|
|
16
16
|
from numpy import exp
|
|
17
17
|
from qdrant_client.http import models as rest
|
|
18
|
-
from qdrant_client.http.exceptions import UnexpectedResponse
|
|
19
18
|
from tqdm import tqdm
|
|
20
19
|
|
|
21
20
|
from .converters import (
|
|
@@ -338,6 +337,9 @@ class QdrantDocumentStore:
|
|
|
338
337
|
def count_documents(self) -> int:
|
|
339
338
|
"""
|
|
340
339
|
Returns the number of documents present in the Document Store.
|
|
340
|
+
|
|
341
|
+
:returns: The number of documents in the collection.
|
|
342
|
+
:raises QdrantStoreError: Counting documents fails.
|
|
341
343
|
"""
|
|
342
344
|
self._initialize_client()
|
|
343
345
|
assert self._client is not None
|
|
@@ -346,15 +348,16 @@ class QdrantDocumentStore:
|
|
|
346
348
|
collection_name=self.index,
|
|
347
349
|
)
|
|
348
350
|
return response.count
|
|
349
|
-
except
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
# we need to catch both.
|
|
353
|
-
return 0
|
|
351
|
+
except Exception as e:
|
|
352
|
+
msg = f"Error when calling QdrantDocumentStore.count_documents(): {e}"
|
|
353
|
+
raise QdrantStoreError(msg) from e
|
|
354
354
|
|
|
355
355
|
async def count_documents_async(self) -> int:
|
|
356
356
|
"""
|
|
357
|
-
Asynchronously returns the number of documents present in the document
|
|
357
|
+
Asynchronously returns the number of documents present in the document store.
|
|
358
|
+
|
|
359
|
+
:returns: The number of documents in the collection.
|
|
360
|
+
:raises QdrantStoreError: Counting documents fails.
|
|
358
361
|
"""
|
|
359
362
|
await self._initialize_async_client()
|
|
360
363
|
assert self._async_client is not None
|
|
@@ -363,11 +366,9 @@ class QdrantDocumentStore:
|
|
|
363
366
|
collection_name=self.index,
|
|
364
367
|
)
|
|
365
368
|
return response.count
|
|
366
|
-
except
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
# we need to catch both.
|
|
370
|
-
return 0
|
|
369
|
+
except Exception as e:
|
|
370
|
+
msg = f"Error when calling QdrantDocumentStore.count_documents_async(): {e}"
|
|
371
|
+
raise QdrantStoreError(msg) from e
|
|
371
372
|
|
|
372
373
|
def filter_documents(
|
|
373
374
|
self,
|
|
@@ -921,38 +922,39 @@ class QdrantDocumentStore:
|
|
|
921
922
|
Deletes all documents from the document store.
|
|
922
923
|
|
|
923
924
|
:param recreate_index: Whether to recreate the index after deleting all documents.
|
|
925
|
+
:raises QdrantStoreError: Deleting documents or recreating the collection fails.
|
|
924
926
|
"""
|
|
925
927
|
|
|
926
928
|
self._initialize_client()
|
|
927
929
|
assert self._client is not None
|
|
928
930
|
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
931
|
+
try:
|
|
932
|
+
if recreate_index:
|
|
933
|
+
# get current collection config as json
|
|
934
|
+
collection_info = self._client.get_collection(collection_name=self.index)
|
|
935
|
+
info_json = collection_info.model_dump()
|
|
933
936
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
+
# deal with the Optional use_sparse_embeddings
|
|
938
|
+
sparse_vectors = info_json["config"]["params"]["sparse_vectors"]
|
|
939
|
+
use_sparse_embeddings = True if sparse_vectors else False
|
|
937
940
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
+
# deal with the Optional sparse_idf
|
|
942
|
+
hnsw_config = info_json["config"]["params"]["vectors"].get("config", {}).get("hnsw_config", None)
|
|
943
|
+
sparse_idf = True if use_sparse_embeddings and hnsw_config else False
|
|
941
944
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
945
|
+
# recreate collection
|
|
946
|
+
self._set_up_collection(
|
|
947
|
+
collection_name=self.index,
|
|
948
|
+
embedding_dim=info_json["config"]["params"]["vectors"]["size"],
|
|
949
|
+
recreate_collection=True,
|
|
950
|
+
similarity=info_json["config"]["params"]["vectors"]["distance"].lower(),
|
|
951
|
+
use_sparse_embeddings=use_sparse_embeddings,
|
|
952
|
+
sparse_idf=sparse_idf,
|
|
953
|
+
on_disk=info_json["config"]["hnsw_config"]["on_disk"],
|
|
954
|
+
payload_fields_to_index=info_json["payload_schema"],
|
|
955
|
+
)
|
|
953
956
|
|
|
954
|
-
|
|
955
|
-
try:
|
|
957
|
+
else:
|
|
956
958
|
self._client.delete(
|
|
957
959
|
collection_name=self.index,
|
|
958
960
|
points_selector=rest.FilterSelector(
|
|
@@ -962,48 +964,48 @@ class QdrantDocumentStore:
|
|
|
962
964
|
),
|
|
963
965
|
wait=self.wait_result_from_api,
|
|
964
966
|
)
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
)
|
|
967
|
+
except Exception as e:
|
|
968
|
+
msg = f"Error when calling QdrantDocumentStore.delete_all_documents(): {e}"
|
|
969
|
+
raise QdrantStoreError(msg) from e
|
|
969
970
|
|
|
970
971
|
async def delete_all_documents_async(self, recreate_index: bool = False) -> None:
|
|
971
972
|
"""
|
|
972
973
|
Asynchronously deletes all documents from the document store.
|
|
973
974
|
|
|
974
975
|
:param recreate_index: Whether to recreate the index after deleting all documents.
|
|
976
|
+
:raises QdrantStoreError: Deleting documents or recreating the collection fails.
|
|
975
977
|
"""
|
|
976
978
|
|
|
977
979
|
await self._initialize_async_client()
|
|
978
980
|
assert self._async_client is not None
|
|
979
981
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
982
|
+
try:
|
|
983
|
+
if recreate_index:
|
|
984
|
+
# get current collection config as json
|
|
985
|
+
collection_info = await self._async_client.get_collection(collection_name=self.index)
|
|
986
|
+
info_json = collection_info.model_dump()
|
|
984
987
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
+
# deal with the Optional use_sparse_embeddings
|
|
989
|
+
sparse_vectors = info_json["config"]["params"]["sparse_vectors"]
|
|
990
|
+
use_sparse_embeddings = True if sparse_vectors else False
|
|
988
991
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
+
# deal with the Optional sparse_idf
|
|
993
|
+
hnsw_config = info_json["config"]["params"]["vectors"].get("config", {}).get("hnsw_config", None)
|
|
994
|
+
sparse_idf = True if use_sparse_embeddings and hnsw_config else False
|
|
992
995
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
996
|
+
# recreate collection
|
|
997
|
+
await self._set_up_collection_async(
|
|
998
|
+
collection_name=self.index,
|
|
999
|
+
embedding_dim=info_json["config"]["params"]["vectors"]["size"],
|
|
1000
|
+
recreate_collection=True,
|
|
1001
|
+
similarity=info_json["config"]["params"]["vectors"]["distance"].lower(),
|
|
1002
|
+
use_sparse_embeddings=use_sparse_embeddings,
|
|
1003
|
+
sparse_idf=sparse_idf,
|
|
1004
|
+
on_disk=info_json["config"]["hnsw_config"]["on_disk"],
|
|
1005
|
+
payload_fields_to_index=info_json["payload_schema"],
|
|
1006
|
+
)
|
|
1004
1007
|
|
|
1005
|
-
|
|
1006
|
-
try:
|
|
1008
|
+
else:
|
|
1007
1009
|
await self._async_client.delete(
|
|
1008
1010
|
collection_name=self.index,
|
|
1009
1011
|
points_selector=rest.FilterSelector(
|
|
@@ -1013,10 +1015,9 @@ class QdrantDocumentStore:
|
|
|
1013
1015
|
),
|
|
1014
1016
|
wait=self.wait_result_from_api,
|
|
1015
1017
|
)
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
)
|
|
1018
|
+
except Exception as e:
|
|
1019
|
+
msg = f"Error when calling QdrantDocumentStore.delete_all_documents_async(): {e}"
|
|
1020
|
+
raise QdrantStoreError(msg) from e
|
|
1020
1021
|
|
|
1021
1022
|
def count_documents_by_filter(self, filters: dict[str, Any]) -> int:
|
|
1022
1023
|
"""
|
|
@@ -1026,6 +1027,7 @@ class QdrantDocumentStore:
|
|
|
1026
1027
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1027
1028
|
|
|
1028
1029
|
:returns: The number of documents that match the filters.
|
|
1030
|
+
:raises QdrantStoreError: Counting documents matching the filters fails.
|
|
1029
1031
|
"""
|
|
1030
1032
|
self._initialize_client()
|
|
1031
1033
|
assert self._client is not None
|
|
@@ -1037,9 +1039,9 @@ class QdrantDocumentStore:
|
|
|
1037
1039
|
count_filter=qdrant_filter,
|
|
1038
1040
|
)
|
|
1039
1041
|
return response.count
|
|
1040
|
-
except
|
|
1041
|
-
|
|
1042
|
-
|
|
1042
|
+
except Exception as e:
|
|
1043
|
+
msg = f"Error when calling QdrantDocumentStore.count_documents_by_filter(): {e}"
|
|
1044
|
+
raise QdrantStoreError(msg) from e
|
|
1043
1045
|
|
|
1044
1046
|
async def count_documents_by_filter_async(self, filters: dict[str, Any]) -> int:
|
|
1045
1047
|
"""
|
|
@@ -1050,6 +1052,7 @@ class QdrantDocumentStore:
|
|
|
1050
1052
|
|
|
1051
1053
|
:returns:
|
|
1052
1054
|
The number of documents that match the filters.
|
|
1055
|
+
:raises QdrantStoreError: Counting documents matching the filters fails.
|
|
1053
1056
|
"""
|
|
1054
1057
|
await self._initialize_async_client()
|
|
1055
1058
|
assert self._async_client is not None
|
|
@@ -1061,9 +1064,9 @@ class QdrantDocumentStore:
|
|
|
1061
1064
|
count_filter=qdrant_filter,
|
|
1062
1065
|
)
|
|
1063
1066
|
return response.count
|
|
1064
|
-
except
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
+
except Exception as e:
|
|
1068
|
+
msg = f"Error when calling QdrantDocumentStore.count_documents_by_filter_async(): {e}"
|
|
1069
|
+
raise QdrantStoreError(msg) from e
|
|
1067
1070
|
|
|
1068
1071
|
def get_metadata_fields_info(self) -> dict[str, dict[str, str]]:
|
|
1069
1072
|
"""
|
|
@@ -1078,6 +1081,7 @@ class QdrantDocumentStore:
|
|
|
1078
1081
|
```python
|
|
1079
1082
|
{"category": {"type": "keyword"}, "priority": {"type": "long"}}
|
|
1080
1083
|
```
|
|
1084
|
+
:raises QdrantStoreError: Retrieving or processing metadata field information fails.
|
|
1081
1085
|
"""
|
|
1082
1086
|
self._initialize_client()
|
|
1083
1087
|
assert self._client is not None
|
|
@@ -1103,9 +1107,9 @@ class QdrantDocumentStore:
|
|
|
1103
1107
|
break
|
|
1104
1108
|
|
|
1105
1109
|
return fields_info
|
|
1106
|
-
except
|
|
1107
|
-
|
|
1108
|
-
|
|
1110
|
+
except Exception as e:
|
|
1111
|
+
msg = f"Error when calling QdrantDocumentStore.get_metadata_fields_info(): {e}"
|
|
1112
|
+
raise QdrantStoreError(msg) from e
|
|
1109
1113
|
|
|
1110
1114
|
async def get_metadata_fields_info_async(self) -> dict[str, dict[str, str]]:
|
|
1111
1115
|
"""
|
|
@@ -1120,6 +1124,7 @@ class QdrantDocumentStore:
|
|
|
1120
1124
|
```python
|
|
1121
1125
|
{"category": {"type": "keyword"}, "priority": {"type": "long"}}
|
|
1122
1126
|
```
|
|
1127
|
+
:raises QdrantStoreError: Retrieving or processing metadata field information fails.
|
|
1123
1128
|
"""
|
|
1124
1129
|
await self._initialize_async_client()
|
|
1125
1130
|
assert self._async_client is not None
|
|
@@ -1145,9 +1150,9 @@ class QdrantDocumentStore:
|
|
|
1145
1150
|
break
|
|
1146
1151
|
|
|
1147
1152
|
return fields_info
|
|
1148
|
-
except
|
|
1149
|
-
|
|
1150
|
-
|
|
1153
|
+
except Exception as e:
|
|
1154
|
+
msg = f"Error when calling QdrantDocumentStore.get_metadata_fields_info_async(): {e}"
|
|
1155
|
+
raise QdrantStoreError(msg) from e
|
|
1151
1156
|
|
|
1152
1157
|
def get_metadata_field_min_max(self, metadata_field: str) -> dict[str, Any]:
|
|
1153
1158
|
"""
|
|
@@ -1158,6 +1163,7 @@ class QdrantDocumentStore:
|
|
|
1158
1163
|
:returns: A dictionary with the keys "min" and "max", where each value is the minimum or maximum value of the
|
|
1159
1164
|
metadata field across all documents. Returns ``{"min": None, "max": None}`` if no documents have
|
|
1160
1165
|
the field.
|
|
1166
|
+
:raises QdrantStoreError: Retrieving or computing the metadata bounds fails.
|
|
1161
1167
|
"""
|
|
1162
1168
|
self._initialize_client()
|
|
1163
1169
|
assert self._client is not None
|
|
@@ -1183,8 +1189,8 @@ class QdrantDocumentStore:
|
|
|
1183
1189
|
|
|
1184
1190
|
return {"min": min_value, "max": max_value}
|
|
1185
1191
|
except Exception as e:
|
|
1186
|
-
|
|
1187
|
-
|
|
1192
|
+
msg = f"Error when calling QdrantDocumentStore.get_metadata_field_min_max(): {e}"
|
|
1193
|
+
raise QdrantStoreError(msg) from e
|
|
1188
1194
|
|
|
1189
1195
|
async def get_metadata_field_min_max_async(self, metadata_field: str) -> dict[str, Any]:
|
|
1190
1196
|
"""
|
|
@@ -1195,6 +1201,7 @@ class QdrantDocumentStore:
|
|
|
1195
1201
|
:returns: A dictionary with the keys "min" and "max", where each value is the minimum or maximum value of the
|
|
1196
1202
|
metadata field across all documents. Returns ``{"min": None, "max": None}`` if no documents have
|
|
1197
1203
|
the field.
|
|
1204
|
+
:raises QdrantStoreError: Retrieving or computing the metadata bounds fails.
|
|
1198
1205
|
"""
|
|
1199
1206
|
await self._initialize_async_client()
|
|
1200
1207
|
assert self._async_client is not None
|
|
@@ -1220,8 +1227,8 @@ class QdrantDocumentStore:
|
|
|
1220
1227
|
|
|
1221
1228
|
return {"min": min_value, "max": max_value}
|
|
1222
1229
|
except Exception as e:
|
|
1223
|
-
|
|
1224
|
-
|
|
1230
|
+
msg = f"Error when calling QdrantDocumentStore.get_metadata_field_min_max_async(): {e}"
|
|
1231
|
+
raise QdrantStoreError(msg) from e
|
|
1225
1232
|
|
|
1226
1233
|
def count_unique_metadata_by_filter(self, filters: dict[str, Any], metadata_fields: list[str]) -> dict[str, int]:
|
|
1227
1234
|
"""
|
|
@@ -1233,6 +1240,7 @@ class QdrantDocumentStore:
|
|
|
1233
1240
|
|
|
1234
1241
|
:returns: A dictionary mapping each metadata field name to the count of its unique values among the filtered
|
|
1235
1242
|
documents.
|
|
1243
|
+
:raises QdrantStoreError: Retrieving or counting unique metadata values fails.
|
|
1236
1244
|
"""
|
|
1237
1245
|
self._initialize_client()
|
|
1238
1246
|
assert self._client is not None
|
|
@@ -1257,8 +1265,8 @@ class QdrantDocumentStore:
|
|
|
1257
1265
|
|
|
1258
1266
|
return {field: len(unique_values_by_field[field]) for field in metadata_fields}
|
|
1259
1267
|
except Exception as e:
|
|
1260
|
-
|
|
1261
|
-
|
|
1268
|
+
msg = f"Error when calling QdrantDocumentStore.count_unique_metadata_by_filter(): {e}"
|
|
1269
|
+
raise QdrantStoreError(msg) from e
|
|
1262
1270
|
|
|
1263
1271
|
async def count_unique_metadata_by_filter_async(
|
|
1264
1272
|
self, filters: dict[str, Any], metadata_fields: list[str]
|
|
@@ -1274,6 +1282,7 @@ class QdrantDocumentStore:
|
|
|
1274
1282
|
|
|
1275
1283
|
:returns: A dictionary mapping each metadata field name to the count of its unique values among the filtered
|
|
1276
1284
|
documents.
|
|
1285
|
+
:raises QdrantStoreError: Retrieving or counting unique metadata values fails.
|
|
1277
1286
|
"""
|
|
1278
1287
|
await self._initialize_async_client()
|
|
1279
1288
|
assert self._async_client is not None
|
|
@@ -1298,8 +1307,8 @@ class QdrantDocumentStore:
|
|
|
1298
1307
|
|
|
1299
1308
|
return {field: len(unique_values_by_field[field]) for field in metadata_fields}
|
|
1300
1309
|
except Exception as e:
|
|
1301
|
-
|
|
1302
|
-
|
|
1310
|
+
msg = f"Error when calling QdrantDocumentStore.count_unique_metadata_by_filter_async(): {e}"
|
|
1311
|
+
raise QdrantStoreError(msg) from e
|
|
1303
1312
|
|
|
1304
1313
|
def get_metadata_field_unique_values(
|
|
1305
1314
|
self,
|
|
@@ -1325,6 +1334,7 @@ class QdrantDocumentStore:
|
|
|
1325
1334
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1326
1335
|
|
|
1327
1336
|
:returns: A tuple containing (list of unique values, total count of unique matching values).
|
|
1337
|
+
:raises QdrantStoreError: Retrieving or processing unique metadata values fails.
|
|
1328
1338
|
"""
|
|
1329
1339
|
self._initialize_client()
|
|
1330
1340
|
assert self._client is not None
|
|
@@ -1353,8 +1363,8 @@ class QdrantDocumentStore:
|
|
|
1353
1363
|
total_count = len(unique_values)
|
|
1354
1364
|
return unique_values[from_ : from_ + size], total_count
|
|
1355
1365
|
except Exception as e:
|
|
1356
|
-
|
|
1357
|
-
|
|
1366
|
+
msg = f"Error when calling QdrantDocumentStore.get_metadata_field_unique_values(): {e}"
|
|
1367
|
+
raise QdrantStoreError(msg) from e
|
|
1358
1368
|
|
|
1359
1369
|
async def get_metadata_field_unique_values_async(
|
|
1360
1370
|
self,
|
|
@@ -1380,6 +1390,7 @@ class QdrantDocumentStore:
|
|
|
1380
1390
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1381
1391
|
|
|
1382
1392
|
:returns: A tuple containing (list of unique values, total count of unique matching values).
|
|
1393
|
+
:raises QdrantStoreError: Retrieving or processing unique metadata values fails.
|
|
1383
1394
|
"""
|
|
1384
1395
|
await self._initialize_async_client()
|
|
1385
1396
|
assert self._async_client is not None
|
|
@@ -1408,8 +1419,8 @@ class QdrantDocumentStore:
|
|
|
1408
1419
|
total_count = len(unique_values)
|
|
1409
1420
|
return unique_values[from_ : from_ + size], total_count
|
|
1410
1421
|
except Exception as e:
|
|
1411
|
-
|
|
1412
|
-
|
|
1422
|
+
msg = f"Error when calling QdrantDocumentStore.get_metadata_field_unique_values_async(): {e}"
|
|
1423
|
+
raise QdrantStoreError(msg) from e
|
|
1413
1424
|
|
|
1414
1425
|
@classmethod
|
|
1415
1426
|
def from_dict(cls, data: dict[str, Any]) -> "QdrantDocumentStore":
|
|
@@ -377,17 +377,19 @@ class TestQdrantDocumentStoreUnit:
|
|
|
377
377
|
document_store._query_by_sparse(query_sparse_embedding=sparse_embedding)
|
|
378
378
|
|
|
379
379
|
@pytest.mark.parametrize(
|
|
380
|
-
("method_name", "args"
|
|
380
|
+
("method_name", "args"),
|
|
381
381
|
[
|
|
382
|
-
("count_documents", ()
|
|
383
|
-
("
|
|
384
|
-
("
|
|
385
|
-
("
|
|
386
|
-
("
|
|
387
|
-
("
|
|
382
|
+
("count_documents", ()),
|
|
383
|
+
("delete_all_documents", (False,)),
|
|
384
|
+
("delete_all_documents", (True,)),
|
|
385
|
+
("count_documents_by_filter", ({},)),
|
|
386
|
+
("get_metadata_fields_info", ()),
|
|
387
|
+
("get_metadata_field_min_max", ("score",)),
|
|
388
|
+
("count_unique_metadata_by_filter", ({}, ["category"])),
|
|
389
|
+
("get_metadata_field_unique_values", ("category",)),
|
|
388
390
|
],
|
|
389
391
|
)
|
|
390
|
-
def
|
|
392
|
+
def test_operations_raise_on_client_errors(self, method_name, args):
|
|
391
393
|
document_store = QdrantDocumentStore(location=":memory:")
|
|
392
394
|
document_store._initialize_client()
|
|
393
395
|
err = ValueError("boom")
|
|
@@ -395,8 +397,11 @@ class TestQdrantDocumentStoreUnit:
|
|
|
395
397
|
patch.object(document_store._client, "count", side_effect=err),
|
|
396
398
|
patch.object(document_store._client, "scroll", side_effect=err),
|
|
397
399
|
patch.object(document_store._client, "get_collection", side_effect=err),
|
|
400
|
+
patch.object(document_store._client, "delete", side_effect=err),
|
|
398
401
|
):
|
|
399
|
-
|
|
402
|
+
with pytest.raises(QdrantStoreError) as exc_info:
|
|
403
|
+
getattr(document_store, method_name)(*args)
|
|
404
|
+
assert exc_info.value.__cause__ is err
|
|
400
405
|
|
|
401
406
|
def test_close(self):
|
|
402
407
|
document_store = QdrantDocumentStore(location=":memory:")
|
|
@@ -141,17 +141,19 @@ class TestQdrantDocumentStoreAsyncUnit:
|
|
|
141
141
|
await document_store.delete_documents_async(["doc-1"])
|
|
142
142
|
|
|
143
143
|
@pytest.mark.parametrize(
|
|
144
|
-
("method_name", "args"
|
|
144
|
+
("method_name", "args"),
|
|
145
145
|
[
|
|
146
|
-
("count_documents_async", ()
|
|
147
|
-
("
|
|
148
|
-
("
|
|
149
|
-
("
|
|
150
|
-
("
|
|
151
|
-
("
|
|
146
|
+
("count_documents_async", ()),
|
|
147
|
+
("delete_all_documents_async", (False,)),
|
|
148
|
+
("delete_all_documents_async", (True,)),
|
|
149
|
+
("count_documents_by_filter_async", ({},)),
|
|
150
|
+
("get_metadata_fields_info_async", ()),
|
|
151
|
+
("get_metadata_field_min_max_async", ("score",)),
|
|
152
|
+
("count_unique_metadata_by_filter_async", ({}, ["category"])),
|
|
153
|
+
("get_metadata_field_unique_values_async", ("category",)),
|
|
152
154
|
],
|
|
153
155
|
)
|
|
154
|
-
async def
|
|
156
|
+
async def test_operations_async_raise_on_client_errors(self, method_name, args):
|
|
155
157
|
document_store = QdrantDocumentStore(location=":memory:")
|
|
156
158
|
await document_store._initialize_async_client()
|
|
157
159
|
err = ValueError("boom")
|
|
@@ -159,8 +161,11 @@ class TestQdrantDocumentStoreAsyncUnit:
|
|
|
159
161
|
patch.object(document_store._async_client, "count", side_effect=err),
|
|
160
162
|
patch.object(document_store._async_client, "scroll", side_effect=err),
|
|
161
163
|
patch.object(document_store._async_client, "get_collection", side_effect=err),
|
|
164
|
+
patch.object(document_store._async_client, "delete", side_effect=err),
|
|
162
165
|
):
|
|
163
|
-
|
|
166
|
+
with pytest.raises(QdrantStoreError) as exc_info:
|
|
167
|
+
await getattr(document_store, method_name)(*args)
|
|
168
|
+
assert exc_info.value.__cause__ is err
|
|
164
169
|
|
|
165
170
|
async def test_close_async(self):
|
|
166
171
|
document_store = QdrantDocumentStore(location=":memory:")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qdrant_haystack-10.6.0 → qdrant_haystack-11.0.0}/src/haystack_integrations/document_stores/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|