pgvector-haystack 1.2.1__tar.gz → 1.3.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.
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/CHANGELOG.md +7 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/PKG-INFO +1 -1
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/src/haystack_integrations/document_stores/pgvector/filters.py +16 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/test_filters.py +58 -2
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/.gitignore +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/LICENSE.txt +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/README.md +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/examples/embedding_retrieval.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/examples/hybrid_retrieval.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/pydoc/config.yml +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/pyproject.toml +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/src/haystack_integrations/components/retrievers/pgvector/__init__.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/src/haystack_integrations/components/retrievers/pgvector/embedding_retriever.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/src/haystack_integrations/components/retrievers/pgvector/keyword_retriever.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/src/haystack_integrations/document_stores/pgvector/__init__.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/src/haystack_integrations/document_stores/pgvector/document_store.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/__init__.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/conftest.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/test_document_store.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/test_embedding_retrieval.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/test_keyword_retrieval.py +0 -0
- {pgvector_haystack-1.2.1 → pgvector_haystack-1.3.0}/tests/test_retrievers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pgvector-haystack
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: An integration of pgvector (vector search extension for Postgres) 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/pgvector/README.md
|
|
@@ -232,6 +232,20 @@ def _in(field: str, value: Any) -> Tuple[str, List]:
|
|
|
232
232
|
return f"{field} = ANY(%s)", [value]
|
|
233
233
|
|
|
234
234
|
|
|
235
|
+
def _like(field: str, value: Any) -> Tuple[str, Any]:
|
|
236
|
+
if not isinstance(value, str):
|
|
237
|
+
msg = f"{field}'s value must be a str when using 'LIKE' "
|
|
238
|
+
raise FilterError(msg)
|
|
239
|
+
return f"{field} LIKE %s", value
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _not_like(field: str, value: Any) -> Tuple[str, Any]:
|
|
243
|
+
if not isinstance(value, str):
|
|
244
|
+
msg = f"{field}'s value must be a str when using 'LIKE' "
|
|
245
|
+
raise FilterError(msg)
|
|
246
|
+
return f"{field} NOT LIKE %s", value
|
|
247
|
+
|
|
248
|
+
|
|
235
249
|
COMPARISON_OPERATORS = {
|
|
236
250
|
"==": _equal,
|
|
237
251
|
"!=": _not_equal,
|
|
@@ -241,4 +255,6 @@ COMPARISON_OPERATORS = {
|
|
|
241
255
|
"<=": _less_than_equal,
|
|
242
256
|
"in": _in,
|
|
243
257
|
"not in": _not_in,
|
|
258
|
+
"like": _like,
|
|
259
|
+
"not like": _not_like,
|
|
244
260
|
}
|
|
@@ -2,7 +2,7 @@ from typing import List
|
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
4
|
from haystack.dataclasses.document import Document
|
|
5
|
-
from haystack.testing.document_store import FilterDocumentsTest
|
|
5
|
+
from haystack.testing.document_store import FilterDocumentsTest, FilterDocumentsTestWithDataframe
|
|
6
6
|
from pandas import DataFrame
|
|
7
7
|
from psycopg.sql import SQL
|
|
8
8
|
from psycopg.types.json import Jsonb
|
|
@@ -17,7 +17,7 @@ from haystack_integrations.document_stores.pgvector.filters import (
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@pytest.mark.integration
|
|
20
|
-
class TestFilters(FilterDocumentsTest):
|
|
20
|
+
class TestFilters(FilterDocumentsTest, FilterDocumentsTestWithDataframe):
|
|
21
21
|
def assert_documents_are_equal(self, received: List[Document], expected: List[Document]):
|
|
22
22
|
"""
|
|
23
23
|
This overrides the default assert_documents_are_equal from FilterDocumentsTest.
|
|
@@ -40,6 +40,62 @@ class TestFilters(FilterDocumentsTest):
|
|
|
40
40
|
@pytest.mark.skip(reason="NOT operator is not supported in PgvectorDocumentStore")
|
|
41
41
|
def test_not_operator(self, document_store, filterable_docs): ...
|
|
42
42
|
|
|
43
|
+
def test_like_operator(self, document_store, filterable_docs):
|
|
44
|
+
document_store.write_documents(filterable_docs)
|
|
45
|
+
filters = {"field": "content", "operator": "like", "value": "%Foo%"}
|
|
46
|
+
result = document_store.filter_documents(filters=filters)
|
|
47
|
+
|
|
48
|
+
self.assert_documents_are_equal(result, [d for d in filterable_docs if "Foo" in d.content])
|
|
49
|
+
|
|
50
|
+
def test_like_operator_startswith(self, document_store, filterable_docs):
|
|
51
|
+
document_store.write_documents(filterable_docs)
|
|
52
|
+
filters = {"field": "content", "operator": "like", "value": "Foo%"}
|
|
53
|
+
result = document_store.filter_documents(filters=filters)
|
|
54
|
+
|
|
55
|
+
self.assert_documents_are_equal(result, [d for d in filterable_docs if d.content.startswith("Foo")])
|
|
56
|
+
|
|
57
|
+
def test_like_operator_nb_chars(self, document_store, filterable_docs):
|
|
58
|
+
document_store.write_documents(filterable_docs)
|
|
59
|
+
filters = {"field": "content", "operator": "like", "value": "A Foobar Document__"}
|
|
60
|
+
result = document_store.filter_documents(filters=filters)
|
|
61
|
+
|
|
62
|
+
self.assert_documents_are_equal(
|
|
63
|
+
result,
|
|
64
|
+
[
|
|
65
|
+
d
|
|
66
|
+
for d in filterable_docs
|
|
67
|
+
if (d.content.startswith("A Foobar Document") and len(d.content) == (len("A Foobar Document") + 2))
|
|
68
|
+
],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def test_not_like_operator(self, document_store, filterable_docs):
|
|
72
|
+
document_store.write_documents(filterable_docs)
|
|
73
|
+
filters = {"field": "content", "operator": "not like", "value": "%Foo%"}
|
|
74
|
+
result = document_store.filter_documents(filters=filters)
|
|
75
|
+
|
|
76
|
+
self.assert_documents_are_equal(result, [d for d in filterable_docs if "Foo" not in d.content])
|
|
77
|
+
|
|
78
|
+
def test_not_like_operator_startswith(self, document_store, filterable_docs):
|
|
79
|
+
document_store.write_documents(filterable_docs)
|
|
80
|
+
filters = {"field": "content", "operator": "not like", "value": "Foo%"}
|
|
81
|
+
result = document_store.filter_documents(filters=filters)
|
|
82
|
+
|
|
83
|
+
self.assert_documents_are_equal(result, [d for d in filterable_docs if not d.content.startswith("Foo")])
|
|
84
|
+
|
|
85
|
+
def test_not_like_operator_nb_chars(self, document_store, filterable_docs):
|
|
86
|
+
document_store.write_documents(filterable_docs)
|
|
87
|
+
filters = {"field": "content", "operator": "not like", "value": "A Foobar Document__"}
|
|
88
|
+
result = document_store.filter_documents(filters=filters)
|
|
89
|
+
|
|
90
|
+
self.assert_documents_are_equal(
|
|
91
|
+
result,
|
|
92
|
+
[
|
|
93
|
+
d
|
|
94
|
+
for d in filterable_docs
|
|
95
|
+
if not (d.content.startswith("A Foobar Document") and len(d.content) == (len("A Foobar Document") + 2))
|
|
96
|
+
],
|
|
97
|
+
)
|
|
98
|
+
|
|
43
99
|
def test_complex_filter(self, document_store, filterable_docs):
|
|
44
100
|
document_store.write_documents(filterable_docs)
|
|
45
101
|
filters = {
|
|
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
|