chroma-haystack 4.1.0__tar.gz → 4.2.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.
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/CHANGELOG.md +13 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/PKG-INFO +4 -4
- chroma_haystack-4.2.0/pydoc/config_docusaurus.yml +16 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/pyproject.toml +6 -5
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/chroma/document_store.py +36 -15
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/tests/test_document_store.py +50 -98
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/tests/test_document_store_async.py +0 -13
- chroma_haystack-4.1.0/pydoc/config_docusaurus.yml +0 -31
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/.gitignore +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/LICENSE +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/README.md +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_01.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_02.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_03.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_04.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_05.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_06.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_07.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_08.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_09.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_10.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_11.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_12.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_20.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_21.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_22.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_23.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_24.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_25.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_26.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_27.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_28.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_29.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_30.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_31.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_32.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_40.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_41.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_42.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_43.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_44.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_45.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_46.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_50.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_51.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_52.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/data/usr_90.txt +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/example/example.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/components/retrievers/chroma/__init__.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/components/retrievers/chroma/retriever.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/components/retrievers/py.typed +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/chroma/__init__.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/chroma/errors.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/chroma/filters.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/chroma/utils.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/py.typed +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/tests/__init__.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/tests/conftest.py +0 -0
- {chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/tests/test_retriever.py +0 -0
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [integrations/chroma-v4.1.1] - 2026-02-10
|
|
4
|
+
|
|
5
|
+
### 📚 Documentation
|
|
6
|
+
|
|
7
|
+
- Fixing curly brackets (#2824)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [integrations/chroma-v4.1.0] - 2026-02-10
|
|
11
|
+
|
|
12
|
+
### 🌀 Miscellaneous
|
|
13
|
+
|
|
14
|
+
- Add metadata query operations to ChromaDocumentStore (#2819)
|
|
15
|
+
|
|
3
16
|
## [integrations/chroma-v4.0.0] - 2026-01-12
|
|
4
17
|
|
|
5
18
|
### 🚀 Features
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chroma-haystack
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/chroma#readme
|
|
5
5
|
Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
|
|
6
6
|
Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/chroma
|
|
7
|
-
Author-email:
|
|
7
|
+
Author-email: deepset GmbH <info@deepset.ai>
|
|
8
8
|
License-Expression: Apache-2.0
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -17,8 +17,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
17
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
18
18
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
|
-
Requires-Dist: chromadb>=1.0
|
|
21
|
-
Requires-Dist: haystack-ai>=2.
|
|
20
|
+
Requires-Dist: chromadb>=1.5.0
|
|
21
|
+
Requires-Dist: haystack-ai>=2.24.0
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
24
|
# chroma-haystack
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
loaders:
|
|
2
|
+
- modules:
|
|
3
|
+
- haystack_integrations.components.retrievers.chroma.retriever
|
|
4
|
+
- haystack_integrations.document_stores.chroma.document_store
|
|
5
|
+
- haystack_integrations.document_stores.chroma.errors
|
|
6
|
+
- haystack_integrations.document_stores.chroma.utils
|
|
7
|
+
search_path: [../src]
|
|
8
|
+
processors:
|
|
9
|
+
- type: filter
|
|
10
|
+
documented_only: true
|
|
11
|
+
skip_empty_modules: true
|
|
12
|
+
renderer:
|
|
13
|
+
description: Chroma integration for Haystack
|
|
14
|
+
id: integrations-chroma
|
|
15
|
+
filename: chroma.md
|
|
16
|
+
title: Chroma
|
|
@@ -10,7 +10,7 @@ readme = "README.md"
|
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = "Apache-2.0"
|
|
12
12
|
keywords = []
|
|
13
|
-
authors = [{ name = "
|
|
13
|
+
authors = [{ name = "deepset GmbH", email = "info@deepset.ai" }]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"License :: OSI Approved :: Apache Software License",
|
|
16
16
|
"Development Status :: 4 - Beta",
|
|
@@ -22,7 +22,10 @@ classifiers = [
|
|
|
22
22
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
23
23
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
24
24
|
]
|
|
25
|
-
dependencies = [
|
|
25
|
+
dependencies = [
|
|
26
|
+
"haystack-ai>=2.24.0",
|
|
27
|
+
"chromadb>=1.5.0"
|
|
28
|
+
]
|
|
26
29
|
|
|
27
30
|
[project.urls]
|
|
28
31
|
Documentation = "https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/chroma#readme"
|
|
@@ -45,7 +48,7 @@ installer = "uv"
|
|
|
45
48
|
dependencies = ["haystack-pydoc-tools", "ruff"]
|
|
46
49
|
|
|
47
50
|
[tool.hatch.envs.default.scripts]
|
|
48
|
-
docs = ["pydoc
|
|
51
|
+
docs = ["haystack-pydoc pydoc/config_docusaurus.yml"]
|
|
49
52
|
fmt = "ruff check --fix {args}; ruff format {args}"
|
|
50
53
|
fmt-check = "ruff check {args} && ruff format --check {args}"
|
|
51
54
|
|
|
@@ -73,8 +76,6 @@ non_interactive = true
|
|
|
73
76
|
check_untyped_defs = true
|
|
74
77
|
disallow_incomplete_defs = true
|
|
75
78
|
|
|
76
|
-
[tool.hatch.metadata]
|
|
77
|
-
allow-direct-references = true
|
|
78
79
|
|
|
79
80
|
[tool.ruff]
|
|
80
81
|
line-length = 120
|
|
@@ -21,7 +21,9 @@ logger = logging.getLogger(__name__)
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
VALID_DISTANCE_FUNCTIONS = "l2", "cosine", "ip"
|
|
24
|
+
# Supported ChromaDB metadata values can be found here: https://cookbook.chromadb.dev/core/concepts/#metadata
|
|
24
25
|
SUPPORTED_TYPES_FOR_METADATA_VALUES = str, int, float, bool
|
|
26
|
+
SUPPORTED_METADATA_VALUES_TYPE = str | int | float | bool
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
class ChromaDocumentStore:
|
|
@@ -533,12 +535,21 @@ class ChromaDocumentStore:
|
|
|
533
535
|
data: dict[str, Any] = {"ids": [doc.id], "documents": [doc.content]}
|
|
534
536
|
|
|
535
537
|
if doc.meta:
|
|
536
|
-
valid_meta = {}
|
|
538
|
+
valid_meta: dict[str, SUPPORTED_METADATA_VALUES_TYPE | list[SUPPORTED_METADATA_VALUES_TYPE]] = {}
|
|
537
539
|
discarded_keys = []
|
|
538
540
|
|
|
539
541
|
for k, v in doc.meta.items():
|
|
540
542
|
if isinstance(v, SUPPORTED_TYPES_FOR_METADATA_VALUES):
|
|
541
543
|
valid_meta[k] = v
|
|
544
|
+
# For list metadata values, list must not be empty, must be of all same type
|
|
545
|
+
# and be one of `SUPPORTED_TYPES_FOR_METADATA_VALUES`
|
|
546
|
+
elif (
|
|
547
|
+
isinstance(v, list)
|
|
548
|
+
and len(v) > 0
|
|
549
|
+
and (first_type := type(v[0])) in SUPPORTED_TYPES_FOR_METADATA_VALUES
|
|
550
|
+
and all(isinstance(item, first_type) for item in v)
|
|
551
|
+
):
|
|
552
|
+
valid_meta[k] = v
|
|
542
553
|
else:
|
|
543
554
|
discarded_keys.append(k)
|
|
544
555
|
|
|
@@ -856,12 +867,13 @@ class ChromaDocumentStore:
|
|
|
856
867
|
else:
|
|
857
868
|
collection = self._collection.get()
|
|
858
869
|
ids = collection.get("ids", [])
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
870
|
+
if ids:
|
|
871
|
+
self._collection.delete(ids=ids) # type: ignore
|
|
872
|
+
logger.info(
|
|
873
|
+
"Deleted all the {n_docs} documents from the collection '{name}'.",
|
|
874
|
+
name=self._collection_name,
|
|
875
|
+
n_docs=len(ids),
|
|
876
|
+
)
|
|
865
877
|
except Exception as e:
|
|
866
878
|
msg = f"Failed to delete all documents from ChromaDB: {e!s}"
|
|
867
879
|
raise DocumentStoreError(msg) from e
|
|
@@ -895,12 +907,13 @@ class ChromaDocumentStore:
|
|
|
895
907
|
else:
|
|
896
908
|
collection = await self._async_collection.get()
|
|
897
909
|
ids = collection.get("ids", [])
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
910
|
+
if ids:
|
|
911
|
+
await self._async_collection.delete(ids=ids) # type: ignore
|
|
912
|
+
logger.info(
|
|
913
|
+
"Deleted all the {n_docs} documents from the collection '{name}'.",
|
|
914
|
+
name=self._collection_name,
|
|
915
|
+
n_docs=len(ids),
|
|
916
|
+
)
|
|
904
917
|
|
|
905
918
|
except Exception as e:
|
|
906
919
|
msg = f"Failed to delete all documents from ChromaDB: {e!s}"
|
|
@@ -1183,7 +1196,11 @@ class ChromaDocumentStore:
|
|
|
1183
1196
|
Can include or omit the "meta." prefix.
|
|
1184
1197
|
:returns: A dictionary with the keys "min" and "max", where each value is
|
|
1185
1198
|
the minimum or maximum value of the metadata field across all documents.
|
|
1186
|
-
Returns
|
|
1199
|
+
Returns:
|
|
1200
|
+
```python
|
|
1201
|
+
{"min": None, "max": None}
|
|
1202
|
+
```
|
|
1203
|
+
if field doesn't exist or has no values.
|
|
1187
1204
|
"""
|
|
1188
1205
|
self._ensure_initialized()
|
|
1189
1206
|
assert self._collection is not None
|
|
@@ -1203,7 +1220,11 @@ class ChromaDocumentStore:
|
|
|
1203
1220
|
Can include or omit the "meta." prefix.
|
|
1204
1221
|
:returns: A dictionary with the keys "min" and "max", where each value is
|
|
1205
1222
|
the minimum or maximum value of the metadata field across all documents.
|
|
1206
|
-
Returns
|
|
1223
|
+
Returns:
|
|
1224
|
+
```python
|
|
1225
|
+
{"min": None, "max": None}
|
|
1226
|
+
```
|
|
1227
|
+
if field doesn't exist or has no values.
|
|
1207
1228
|
"""
|
|
1208
1229
|
await self._ensure_initialized_async()
|
|
1209
1230
|
assert self._async_collection is not None
|
|
@@ -14,8 +14,12 @@ from haystack.dataclasses import ByteStream, Document
|
|
|
14
14
|
from haystack.testing.document_store import (
|
|
15
15
|
TEST_EMBEDDING_1,
|
|
16
16
|
CountDocumentsTest,
|
|
17
|
+
DeleteAllTest,
|
|
18
|
+
DeleteByFilterTest,
|
|
17
19
|
DeleteDocumentsTest,
|
|
20
|
+
FilterableDocsFixtureMixin,
|
|
18
21
|
FilterDocumentsTest,
|
|
22
|
+
UpdateByFilterTest,
|
|
19
23
|
)
|
|
20
24
|
|
|
21
25
|
from haystack_integrations.document_stores.chroma import ChromaDocumentStore
|
|
@@ -34,7 +38,15 @@ def clear_chroma_system_cache():
|
|
|
34
38
|
SharedSystemClient.clear_system_cache()
|
|
35
39
|
|
|
36
40
|
|
|
37
|
-
class TestDocumentStore(
|
|
41
|
+
class TestDocumentStore(
|
|
42
|
+
CountDocumentsTest,
|
|
43
|
+
DeleteDocumentsTest,
|
|
44
|
+
FilterDocumentsTest,
|
|
45
|
+
FilterableDocsFixtureMixin,
|
|
46
|
+
UpdateByFilterTest,
|
|
47
|
+
DeleteAllTest,
|
|
48
|
+
DeleteByFilterTest,
|
|
49
|
+
):
|
|
38
50
|
"""
|
|
39
51
|
Common test cases will be provided by `DocumentStoreBaseTests` but
|
|
40
52
|
you can add more to this class.
|
|
@@ -112,16 +124,6 @@ class TestDocumentStore(CountDocumentsTest, DeleteDocumentsTest, FilterDocuments
|
|
|
112
124
|
store._ensure_initialized()
|
|
113
125
|
assert store._client.get_settings().anonymized_telemetry is False
|
|
114
126
|
|
|
115
|
-
def test_invalid_client_settings(self, clear_chroma_system_cache):
|
|
116
|
-
store = ChromaDocumentStore(
|
|
117
|
-
client_settings={
|
|
118
|
-
"invalid_setting_name": "some_value",
|
|
119
|
-
"another_fake_setting": 123,
|
|
120
|
-
}
|
|
121
|
-
)
|
|
122
|
-
with pytest.raises(ValueError, match="Invalid client_settings"):
|
|
123
|
-
store._ensure_initialized()
|
|
124
|
-
|
|
125
127
|
def test_to_dict(self, request):
|
|
126
128
|
ds = ChromaDocumentStore(
|
|
127
129
|
collection_name=request.node.name,
|
|
@@ -253,15 +255,17 @@ class TestDocumentStore(CountDocumentsTest, DeleteDocumentsTest, FilterDocuments
|
|
|
253
255
|
|
|
254
256
|
assert document_store.filter_documents()[0].embedding == pytest.approx(TEST_EMBEDDING_1)
|
|
255
257
|
|
|
256
|
-
def test_write_documents_unsupported_meta_values(self, document_store: ChromaDocumentStore):
|
|
258
|
+
def test_write_documents_unsupported_meta_values(self, document_store: ChromaDocumentStore) -> None:
|
|
257
259
|
"""
|
|
258
260
|
Unsupported meta values should be removed from the documents before writing them to the database
|
|
259
261
|
"""
|
|
260
262
|
|
|
261
263
|
docs = [
|
|
262
264
|
Document(content="test doc 1", meta={"invalid": {"dict": "value"}}),
|
|
263
|
-
Document(content="test doc 2", meta={"invalid": ["list", "value"]}),
|
|
264
|
-
Document(content="test doc 3", meta={"
|
|
265
|
+
Document(content="test doc 2", meta={"invalid": [["list", "value"]]}),
|
|
266
|
+
Document(content="test doc 3", meta={"invalid": []}),
|
|
267
|
+
Document(content="test doc 4", meta={"invalid": ["list", 2]}),
|
|
268
|
+
Document(content="test doc 5", meta={"ok": 123}),
|
|
265
269
|
]
|
|
266
270
|
|
|
267
271
|
document_store.write_documents(docs)
|
|
@@ -269,11 +273,41 @@ class TestDocumentStore(CountDocumentsTest, DeleteDocumentsTest, FilterDocuments
|
|
|
269
273
|
written_docs = document_store.filter_documents()
|
|
270
274
|
written_docs.sort(key=lambda x: x.content)
|
|
271
275
|
|
|
272
|
-
assert len(written_docs) ==
|
|
276
|
+
assert len(written_docs) == 5
|
|
273
277
|
assert [doc.id for doc in written_docs] == [doc.id for doc in docs]
|
|
274
278
|
assert written_docs[0].meta == {}
|
|
275
279
|
assert written_docs[1].meta == {}
|
|
276
|
-
assert written_docs[2].meta == {
|
|
280
|
+
assert written_docs[2].meta == {}
|
|
281
|
+
assert written_docs[3].meta == {}
|
|
282
|
+
assert written_docs[4].meta == {"ok": 123}
|
|
283
|
+
|
|
284
|
+
def test_write_documents_supported_meta_values(self, document_store: ChromaDocumentStore) -> None:
|
|
285
|
+
"""
|
|
286
|
+
Unsupported meta values should be removed from the documents before writing them to the database
|
|
287
|
+
"""
|
|
288
|
+
|
|
289
|
+
docs = [
|
|
290
|
+
Document(content="test doc 1", meta={"ok": "test"}),
|
|
291
|
+
Document(content="test doc 2", meta={"ok": ["list", "value"]}),
|
|
292
|
+
Document(content="test doc 3", meta={"ok": [True, False, True]}),
|
|
293
|
+
Document(content="test doc 4", meta={"ok": [1, 2, 3]}),
|
|
294
|
+
Document(content="test doc 5", meta={"ok": [1.1, 2.2, 3.3]}),
|
|
295
|
+
Document(content="test doc 6", meta={"ok": 123}),
|
|
296
|
+
]
|
|
297
|
+
|
|
298
|
+
document_store.write_documents(docs)
|
|
299
|
+
|
|
300
|
+
written_docs = document_store.filter_documents()
|
|
301
|
+
written_docs.sort(key=lambda x: x.content)
|
|
302
|
+
|
|
303
|
+
assert len(written_docs) == 6
|
|
304
|
+
assert [doc.id for doc in written_docs] == [doc.id for doc in docs]
|
|
305
|
+
assert written_docs[0].meta == {"ok": "test"}
|
|
306
|
+
assert written_docs[1].meta == {"ok": ["list", "value"]}
|
|
307
|
+
assert written_docs[2].meta == {"ok": [True, False, True]}
|
|
308
|
+
assert written_docs[3].meta == {"ok": [1, 2, 3]}
|
|
309
|
+
assert written_docs[4].meta == {"ok": [1.1, 2.2, 3.3]}
|
|
310
|
+
assert written_docs[5].meta == {"ok": 123}
|
|
277
311
|
|
|
278
312
|
def test_documents_with_content_none_are_not_stored(self, document_store: ChromaDocumentStore):
|
|
279
313
|
document_store.write_documents([Document(content=None)])
|
|
@@ -465,88 +499,6 @@ class TestDocumentStore(CountDocumentsTest, DeleteDocumentsTest, FilterDocuments
|
|
|
465
499
|
assert len(results) == 1
|
|
466
500
|
assert results[0].content == "New document after delete all"
|
|
467
501
|
|
|
468
|
-
def test_delete_by_filter(self, document_store: ChromaDocumentStore):
|
|
469
|
-
docs = [
|
|
470
|
-
Document(content="Doc 1", meta={"category": "A"}),
|
|
471
|
-
Document(content="Doc 2", meta={"category": "B"}),
|
|
472
|
-
Document(content="Doc 3", meta={"category": "A"}),
|
|
473
|
-
]
|
|
474
|
-
document_store.write_documents(docs)
|
|
475
|
-
assert document_store.count_documents() == 3
|
|
476
|
-
|
|
477
|
-
# delete documents with category="A"
|
|
478
|
-
deleted_count = document_store.delete_by_filter(
|
|
479
|
-
filters={"field": "meta.category", "operator": "==", "value": "A"}
|
|
480
|
-
)
|
|
481
|
-
assert deleted_count == 2
|
|
482
|
-
assert document_store.count_documents() == 1
|
|
483
|
-
|
|
484
|
-
# verify only category B remains
|
|
485
|
-
remaining_docs = document_store.filter_documents()
|
|
486
|
-
assert len(remaining_docs) == 1
|
|
487
|
-
assert remaining_docs[0].meta["category"] == "B"
|
|
488
|
-
|
|
489
|
-
def test_delete_by_filter_no_matches(self, document_store: ChromaDocumentStore):
|
|
490
|
-
docs = [
|
|
491
|
-
Document(content="Doc 1", meta={"category": "A"}),
|
|
492
|
-
Document(content="Doc 2", meta={"category": "B"}),
|
|
493
|
-
]
|
|
494
|
-
document_store.write_documents(docs)
|
|
495
|
-
assert document_store.count_documents() == 2
|
|
496
|
-
|
|
497
|
-
# delete documents with category="C" (no matches)
|
|
498
|
-
deleted_count = document_store.delete_by_filter(
|
|
499
|
-
filters={"field": "meta.category", "operator": "==", "value": "C"}
|
|
500
|
-
)
|
|
501
|
-
assert deleted_count == 0
|
|
502
|
-
assert document_store.count_documents() == 2
|
|
503
|
-
|
|
504
|
-
def test_update_by_filter(self, document_store: ChromaDocumentStore):
|
|
505
|
-
docs = [
|
|
506
|
-
Document(content="Doc 1", meta={"category": "A", "status": "draft"}),
|
|
507
|
-
Document(content="Doc 2", meta={"category": "B", "status": "draft"}),
|
|
508
|
-
Document(content="Doc 3", meta={"category": "A", "status": "draft"}),
|
|
509
|
-
]
|
|
510
|
-
document_store.write_documents(docs)
|
|
511
|
-
assert document_store.count_documents() == 3
|
|
512
|
-
|
|
513
|
-
# update status for category="A" documents
|
|
514
|
-
updated_count = document_store.update_by_filter(
|
|
515
|
-
filters={"field": "meta.category", "operator": "==", "value": "A"}, meta={"status": "published"}
|
|
516
|
-
)
|
|
517
|
-
assert updated_count == 2
|
|
518
|
-
|
|
519
|
-
# verify the updated documents have the new metadata
|
|
520
|
-
published_docs = document_store.filter_documents(
|
|
521
|
-
filters={"field": "meta.status", "operator": "==", "value": "published"}
|
|
522
|
-
)
|
|
523
|
-
assert len(published_docs) == 2
|
|
524
|
-
for doc in published_docs:
|
|
525
|
-
assert doc.meta["status"] == "published"
|
|
526
|
-
assert doc.meta["category"] == "A"
|
|
527
|
-
|
|
528
|
-
# Verify documents with category="B" were not updated
|
|
529
|
-
unpublished_docs = document_store.filter_documents(
|
|
530
|
-
filters={"field": "meta.category", "operator": "==", "value": "B"}
|
|
531
|
-
)
|
|
532
|
-
assert len(unpublished_docs) == 1
|
|
533
|
-
assert unpublished_docs[0].meta["status"] == "draft"
|
|
534
|
-
|
|
535
|
-
def test_update_by_filter_no_matches(self, document_store: ChromaDocumentStore):
|
|
536
|
-
docs = [
|
|
537
|
-
Document(content="Doc 1", meta={"category": "A"}),
|
|
538
|
-
Document(content="Doc 2", meta={"category": "B"}),
|
|
539
|
-
]
|
|
540
|
-
document_store.write_documents(docs)
|
|
541
|
-
assert document_store.count_documents() == 2
|
|
542
|
-
|
|
543
|
-
# Try to update documents with category="C" (no matches)
|
|
544
|
-
updated_count = document_store.update_by_filter(
|
|
545
|
-
filters={"field": "meta.category", "operator": "==", "value": "C"}, meta={"status": "published"}
|
|
546
|
-
)
|
|
547
|
-
assert updated_count == 0
|
|
548
|
-
assert document_store.count_documents() == 2
|
|
549
|
-
|
|
550
502
|
@pytest.mark.integration
|
|
551
503
|
def test_search_embeddings(self, document_store: ChromaDocumentStore):
|
|
552
504
|
query_embedding = TEST_EMBEDDING_1
|
|
@@ -107,19 +107,6 @@ class TestDocumentStoreAsync:
|
|
|
107
107
|
await store._ensure_initialized_async()
|
|
108
108
|
assert store._async_client.get_settings().anonymized_telemetry is False
|
|
109
109
|
|
|
110
|
-
async def test_invalid_client_settings_async(self):
|
|
111
|
-
store = ChromaDocumentStore(
|
|
112
|
-
host="localhost",
|
|
113
|
-
port=8000,
|
|
114
|
-
client_settings={
|
|
115
|
-
"invalid_setting_name": "some_value",
|
|
116
|
-
"another_fake_setting": 123,
|
|
117
|
-
},
|
|
118
|
-
collection_name=f"{uuid.uuid1()}-async-invalid",
|
|
119
|
-
)
|
|
120
|
-
with pytest.raises(ValueError, match="Invalid client_settings"):
|
|
121
|
-
await store._ensure_initialized_async()
|
|
122
|
-
|
|
123
110
|
async def test_search_async(self):
|
|
124
111
|
document_store = ChromaDocumentStore(host="localhost", port=8000, collection_name="my_custom_collection")
|
|
125
112
|
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
loaders:
|
|
2
|
-
- ignore_when_discovered:
|
|
3
|
-
- __init__
|
|
4
|
-
modules:
|
|
5
|
-
- haystack_integrations.components.retrievers.chroma.retriever
|
|
6
|
-
- haystack_integrations.document_stores.chroma.document_store
|
|
7
|
-
- haystack_integrations.document_stores.chroma.errors
|
|
8
|
-
- haystack_integrations.document_stores.chroma.utils
|
|
9
|
-
search_path:
|
|
10
|
-
- ../src
|
|
11
|
-
type: haystack_pydoc_tools.loaders.CustomPythonLoader
|
|
12
|
-
processors:
|
|
13
|
-
- do_not_filter_modules: false
|
|
14
|
-
documented_only: true
|
|
15
|
-
expression: null
|
|
16
|
-
skip_empty_modules: true
|
|
17
|
-
type: filter
|
|
18
|
-
- type: smart
|
|
19
|
-
- type: crossref
|
|
20
|
-
renderer:
|
|
21
|
-
description: Chroma integration for Haystack
|
|
22
|
-
id: integrations-chroma
|
|
23
|
-
markdown:
|
|
24
|
-
add_member_class_prefix: false
|
|
25
|
-
add_method_class_prefix: true
|
|
26
|
-
classdef_code_block: false
|
|
27
|
-
descriptive_class_title: false
|
|
28
|
-
descriptive_module_title: true
|
|
29
|
-
filename: chroma.md
|
|
30
|
-
title: Chroma
|
|
31
|
-
type: haystack_pydoc_tools.renderers.DocusaurusRenderer
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chroma_haystack-4.1.0 → chroma_haystack-4.2.0}/src/haystack_integrations/document_stores/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|