weaviate-haystack 1.0.2__tar.gz → 2.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.
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/.gitignore +1 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/PKG-INFO +3 -3
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/docker-compose.yml +2 -2
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/pydoc/config.yml +1 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/pyproject.toml +13 -10
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/src/haystack_integrations/components/retrievers/weaviate/bm25_retriever.py +41 -4
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/src/haystack_integrations/components/retrievers/weaviate/embedding_retriever.py +52 -9
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/src/haystack_integrations/document_stores/weaviate/_filters.py +41 -60
- weaviate_haystack-2.0.0/src/haystack_integrations/document_stores/weaviate/document_store.py +497 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/test_bm25_retriever.py +0 -8
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/test_document_store.py +91 -53
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/test_embedding_retriever.py +2 -10
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/test_filters.py +1 -1
- weaviate_haystack-1.0.2/src/haystack_integrations/document_stores/weaviate/document_store.py +0 -470
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/LICENSE.txt +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/README.md +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/src/haystack_integrations/components/retrievers/weaviate/__init__.py +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/src/haystack_integrations/document_stores/weaviate/__init__.py +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/src/haystack_integrations/document_stores/weaviate/auth.py +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/__init__.py +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/conftest.py +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/test_auth.py +0 -0
- {weaviate_haystack-1.0.2 → weaviate_haystack-2.0.0}/tests/test_files/robot1.jpg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: weaviate-haystack
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: An integration of Weaviate vector database 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/weaviate/README.md
|
|
@@ -21,7 +21,7 @@ Requires-Python: >=3.8
|
|
|
21
21
|
Requires-Dist: haystack-ai
|
|
22
22
|
Requires-Dist: haystack-pydoc-tools
|
|
23
23
|
Requires-Dist: python-dateutil
|
|
24
|
-
Requires-Dist: weaviate-client
|
|
24
|
+
Requires-Dist: weaviate-client
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
|
|
27
27
|
# weaviate-haystack
|
|
@@ -8,7 +8,7 @@ services:
|
|
|
8
8
|
- '8080'
|
|
9
9
|
- --scheme
|
|
10
10
|
- http
|
|
11
|
-
image: semitechnologies/weaviate:1.
|
|
11
|
+
image: semitechnologies/weaviate:1.24.5
|
|
12
12
|
ports:
|
|
13
13
|
- 8080:8080
|
|
14
14
|
- 50051:50051
|
|
@@ -19,4 +19,4 @@ services:
|
|
|
19
19
|
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
|
|
20
20
|
DEFAULT_VECTORIZER_MODULE: 'none'
|
|
21
21
|
ENABLE_MODULES: ''
|
|
22
|
-
CLUSTER_HOSTNAME: 'node1'
|
|
22
|
+
CLUSTER_HOSTNAME: 'node1'
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
26
|
"haystack-ai",
|
|
27
|
-
"weaviate-client
|
|
27
|
+
"weaviate-client",
|
|
28
28
|
"haystack-pydoc-tools",
|
|
29
29
|
"python-dateutil",
|
|
30
30
|
]
|
|
@@ -67,12 +67,12 @@ fmt = ["black {args:.}", "ruff --fix {args:.}", "style"]
|
|
|
67
67
|
all = ["style", "typing"]
|
|
68
68
|
|
|
69
69
|
[tool.black]
|
|
70
|
-
target-version = ["
|
|
70
|
+
target-version = ["py38"]
|
|
71
71
|
line-length = 120
|
|
72
72
|
skip-string-normalization = true
|
|
73
73
|
|
|
74
74
|
[tool.ruff]
|
|
75
|
-
target-version = "
|
|
75
|
+
target-version = "py38"
|
|
76
76
|
line-length = 120
|
|
77
77
|
select = [
|
|
78
78
|
"A",
|
|
@@ -133,17 +133,20 @@ ban-relative-imports = "parents"
|
|
|
133
133
|
"tests/**/*" = ["PLR2004", "S101", "TID252"]
|
|
134
134
|
|
|
135
135
|
[tool.coverage.run]
|
|
136
|
-
|
|
136
|
+
source = ["haystack_integrations"]
|
|
137
137
|
branch = true
|
|
138
|
-
parallel =
|
|
138
|
+
parallel = false
|
|
139
139
|
|
|
140
140
|
|
|
141
|
-
[tool.coverage.paths]
|
|
142
|
-
weaviate_haystack = ["src/haystack_integrations", "*/weaviate-haystack/src"]
|
|
143
|
-
tests = ["tests", "*/weaviate-haystack/tests"]
|
|
144
|
-
|
|
145
141
|
[tool.coverage.report]
|
|
146
|
-
|
|
142
|
+
omit = ["*/tests/*", "*/__init__.py"]
|
|
143
|
+
show_missing=true
|
|
144
|
+
exclude_lines = [
|
|
145
|
+
"no cov",
|
|
146
|
+
"if __name__ == .__main__.:",
|
|
147
|
+
"if TYPE_CHECKING:",
|
|
148
|
+
]
|
|
149
|
+
|
|
147
150
|
|
|
148
151
|
[[tool.mypy.overrides]]
|
|
149
152
|
module = [
|
|
@@ -7,7 +7,17 @@ from haystack_integrations.document_stores.weaviate import WeaviateDocumentStore
|
|
|
7
7
|
@component
|
|
8
8
|
class WeaviateBM25Retriever:
|
|
9
9
|
"""
|
|
10
|
-
|
|
10
|
+
A component for retrieving documents from Weaviate using the BM25 algorithm.
|
|
11
|
+
|
|
12
|
+
Example usage:
|
|
13
|
+
```python
|
|
14
|
+
from haystack_integrations.document_stores.weaviate.document_store import WeaviateDocumentStore
|
|
15
|
+
from haystack_integrations.components.retrievers.weaviate.bm25_retriever import WeaviateBM25Retriever
|
|
16
|
+
|
|
17
|
+
document_store = WeaviateDocumentStore(url="http://localhost:8080")
|
|
18
|
+
retriever = WeaviateBM25Retriever(document_store=document_store)
|
|
19
|
+
retriever.run(query="How to make a pizza", top_k=3)
|
|
20
|
+
```
|
|
11
21
|
"""
|
|
12
22
|
|
|
13
23
|
def __init__(
|
|
@@ -20,15 +30,24 @@ class WeaviateBM25Retriever:
|
|
|
20
30
|
"""
|
|
21
31
|
Create a new instance of WeaviateBM25Retriever.
|
|
22
32
|
|
|
23
|
-
:param document_store:
|
|
24
|
-
|
|
25
|
-
:param
|
|
33
|
+
:param document_store:
|
|
34
|
+
Instance of WeaviateDocumentStore that will be used from this retriever.
|
|
35
|
+
:param filters:
|
|
36
|
+
Custom filters applied when running the retriever
|
|
37
|
+
:param top_k:
|
|
38
|
+
Maximum number of documents to return
|
|
26
39
|
"""
|
|
27
40
|
self._document_store = document_store
|
|
28
41
|
self._filters = filters or {}
|
|
29
42
|
self._top_k = top_k
|
|
30
43
|
|
|
31
44
|
def to_dict(self) -> Dict[str, Any]:
|
|
45
|
+
"""
|
|
46
|
+
Serializes the component to a dictionary.
|
|
47
|
+
|
|
48
|
+
:returns:
|
|
49
|
+
Dictionary with serialized data.
|
|
50
|
+
"""
|
|
32
51
|
return default_to_dict(
|
|
33
52
|
self,
|
|
34
53
|
filters=self._filters,
|
|
@@ -38,6 +57,14 @@ class WeaviateBM25Retriever:
|
|
|
38
57
|
|
|
39
58
|
@classmethod
|
|
40
59
|
def from_dict(cls, data: Dict[str, Any]) -> "WeaviateBM25Retriever":
|
|
60
|
+
"""
|
|
61
|
+
Deserializes the component from a dictionary.
|
|
62
|
+
|
|
63
|
+
:param data:
|
|
64
|
+
Dictionary to deserialize from.
|
|
65
|
+
:returns:
|
|
66
|
+
Deserialized component.
|
|
67
|
+
"""
|
|
41
68
|
data["init_parameters"]["document_store"] = WeaviateDocumentStore.from_dict(
|
|
42
69
|
data["init_parameters"]["document_store"]
|
|
43
70
|
)
|
|
@@ -45,6 +72,16 @@ class WeaviateBM25Retriever:
|
|
|
45
72
|
|
|
46
73
|
@component.output_types(documents=List[Document])
|
|
47
74
|
def run(self, query: str, filters: Optional[Dict[str, Any]] = None, top_k: Optional[int] = None):
|
|
75
|
+
"""
|
|
76
|
+
Retrieves documents from Weaviate using the BM25 algorithm.
|
|
77
|
+
|
|
78
|
+
:param query:
|
|
79
|
+
The query text.
|
|
80
|
+
:param filters:
|
|
81
|
+
Filters to use when running the retriever.
|
|
82
|
+
:param top_k:
|
|
83
|
+
The maximum number of documents to return.
|
|
84
|
+
"""
|
|
48
85
|
filters = filters or self._filters
|
|
49
86
|
top_k = top_k or self._top_k
|
|
50
87
|
documents = self._document_store._bm25_retrieval(query=query, filters=filters, top_k=top_k)
|
|
@@ -20,16 +20,22 @@ class WeaviateEmbeddingRetriever:
|
|
|
20
20
|
certainty: Optional[float] = None,
|
|
21
21
|
):
|
|
22
22
|
"""
|
|
23
|
-
|
|
24
|
-
Raises ValueError if both `distance` and `certainty` are provided.
|
|
25
|
-
See the official Weaviate documentation to learn more about the `distance` and `certainty` parameters:
|
|
26
|
-
https://weaviate.io/developers/weaviate/api/graphql/search-operators#variables
|
|
23
|
+
Creates a new instance of WeaviateEmbeddingRetriever.
|
|
27
24
|
|
|
28
|
-
:param document_store:
|
|
29
|
-
|
|
30
|
-
:param
|
|
31
|
-
|
|
32
|
-
:param
|
|
25
|
+
:param document_store:
|
|
26
|
+
Instance of WeaviateDocumentStore that will be used from this retriever.
|
|
27
|
+
:param filters:
|
|
28
|
+
Custom filters applied when running the retriever.
|
|
29
|
+
:param top_k:
|
|
30
|
+
Maximum number of documents to return.
|
|
31
|
+
:param distance:
|
|
32
|
+
The maximum allowed distance between Documents' embeddings.
|
|
33
|
+
:param certainty:
|
|
34
|
+
Normalized distance between the result item and the search vector.
|
|
35
|
+
:raises ValueError:
|
|
36
|
+
If both `distance` and `certainty` are provided.
|
|
37
|
+
See https://weaviate.io/developers/weaviate/api/graphql/search-operators#variables to learn more about
|
|
38
|
+
`distance` and `certainty` parameters.
|
|
33
39
|
"""
|
|
34
40
|
if distance is not None and certainty is not None:
|
|
35
41
|
msg = "Can't use 'distance' and 'certainty' parameters together"
|
|
@@ -42,6 +48,12 @@ class WeaviateEmbeddingRetriever:
|
|
|
42
48
|
self._certainty = certainty
|
|
43
49
|
|
|
44
50
|
def to_dict(self) -> Dict[str, Any]:
|
|
51
|
+
"""
|
|
52
|
+
Serializes the component to a dictionary.
|
|
53
|
+
|
|
54
|
+
:returns:
|
|
55
|
+
Dictionary with serialized data.
|
|
56
|
+
"""
|
|
45
57
|
return default_to_dict(
|
|
46
58
|
self,
|
|
47
59
|
filters=self._filters,
|
|
@@ -53,6 +65,14 @@ class WeaviateEmbeddingRetriever:
|
|
|
53
65
|
|
|
54
66
|
@classmethod
|
|
55
67
|
def from_dict(cls, data: Dict[str, Any]) -> "WeaviateEmbeddingRetriever":
|
|
68
|
+
"""
|
|
69
|
+
Deserializes the component from a dictionary.
|
|
70
|
+
|
|
71
|
+
:param data:
|
|
72
|
+
Dictionary to deserialize from.
|
|
73
|
+
:returns:
|
|
74
|
+
Deserialized component.
|
|
75
|
+
"""
|
|
56
76
|
data["init_parameters"]["document_store"] = WeaviateDocumentStore.from_dict(
|
|
57
77
|
data["init_parameters"]["document_store"]
|
|
58
78
|
)
|
|
@@ -67,10 +87,33 @@ class WeaviateEmbeddingRetriever:
|
|
|
67
87
|
distance: Optional[float] = None,
|
|
68
88
|
certainty: Optional[float] = None,
|
|
69
89
|
):
|
|
90
|
+
"""
|
|
91
|
+
Retrieves documents from Weaviate using the vector search.
|
|
92
|
+
|
|
93
|
+
:param query_embedding:
|
|
94
|
+
Embedding of the query.
|
|
95
|
+
:param filters:
|
|
96
|
+
Filters to use when running the retriever.
|
|
97
|
+
:param top_k:
|
|
98
|
+
The maximum number of documents to return.
|
|
99
|
+
:param distance:
|
|
100
|
+
The maximum allowed distance between Documents' embeddings.
|
|
101
|
+
:param certainty:
|
|
102
|
+
Normalized distance between the result item and the search vector.
|
|
103
|
+
:raises ValueError:
|
|
104
|
+
If both `distance` and `certainty` are provided.
|
|
105
|
+
See https://weaviate.io/developers/weaviate/api/graphql/search-operators#variables to learn more about
|
|
106
|
+
`distance` and `certainty` parameters.
|
|
107
|
+
"""
|
|
70
108
|
filters = filters or self._filters
|
|
71
109
|
top_k = top_k or self._top_k
|
|
110
|
+
|
|
72
111
|
distance = distance or self._distance
|
|
73
112
|
certainty = certainty or self._certainty
|
|
113
|
+
if distance is not None and certainty is not None:
|
|
114
|
+
msg = "Can't use 'distance' and 'certainty' parameters together"
|
|
115
|
+
raise ValueError(msg)
|
|
116
|
+
|
|
74
117
|
documents = self._document_store._embedding_retrieval(
|
|
75
118
|
query_embedding=query_embedding,
|
|
76
119
|
filters=filters,
|
|
@@ -4,8 +4,11 @@ from dateutil import parser
|
|
|
4
4
|
from haystack.errors import FilterError
|
|
5
5
|
from pandas import DataFrame
|
|
6
6
|
|
|
7
|
+
import weaviate
|
|
8
|
+
from weaviate.collections.classes.filters import Filter, FilterReturn
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
def convert_filters(filters: Dict[str, Any]) -> FilterReturn:
|
|
9
12
|
"""
|
|
10
13
|
Convert filters from Haystack format to Weaviate format.
|
|
11
14
|
"""
|
|
@@ -14,7 +17,7 @@ def convert_filters(filters: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
14
17
|
raise FilterError(msg)
|
|
15
18
|
|
|
16
19
|
if "field" in filters:
|
|
17
|
-
return
|
|
20
|
+
return Filter.all_of([_parse_comparison_condition(filters)])
|
|
18
21
|
return _parse_logical_condition(filters)
|
|
19
22
|
|
|
20
23
|
|
|
@@ -29,7 +32,7 @@ OPERATOR_INVERSE = {
|
|
|
29
32
|
"not in": "in",
|
|
30
33
|
"AND": "OR",
|
|
31
34
|
"OR": "AND",
|
|
32
|
-
"NOT": "
|
|
35
|
+
"NOT": "OR",
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
|
|
@@ -51,7 +54,13 @@ def _invert_condition(filters: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
51
54
|
return inverted_condition
|
|
52
55
|
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
LOGICAL_OPERATORS = {
|
|
58
|
+
"AND": Filter.all_of,
|
|
59
|
+
"OR": Filter.any_of,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _parse_logical_condition(condition: Dict[str, Any]) -> FilterReturn:
|
|
55
64
|
if "operator" not in condition:
|
|
56
65
|
msg = f"'operator' key missing in {condition}"
|
|
57
66
|
raise FilterError(msg)
|
|
@@ -67,7 +76,7 @@ def _parse_logical_condition(condition: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
67
76
|
operands.append(_parse_logical_condition(c))
|
|
68
77
|
else:
|
|
69
78
|
operands.append(_parse_comparison_condition(c))
|
|
70
|
-
return
|
|
79
|
+
return LOGICAL_OPERATORS[operator](operands)
|
|
71
80
|
elif operator == "NOT":
|
|
72
81
|
inverted_conditions = _invert_condition(condition)
|
|
73
82
|
return _parse_logical_condition(inverted_conditions)
|
|
@@ -76,28 +85,6 @@ def _parse_logical_condition(condition: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
76
85
|
raise FilterError(msg)
|
|
77
86
|
|
|
78
87
|
|
|
79
|
-
def _infer_value_type(value: Any) -> str:
|
|
80
|
-
if value is None:
|
|
81
|
-
return "valueNull"
|
|
82
|
-
|
|
83
|
-
if isinstance(value, bool):
|
|
84
|
-
return "valueBoolean"
|
|
85
|
-
if isinstance(value, int):
|
|
86
|
-
return "valueInt"
|
|
87
|
-
if isinstance(value, float):
|
|
88
|
-
return "valueNumber"
|
|
89
|
-
|
|
90
|
-
if isinstance(value, str):
|
|
91
|
-
try:
|
|
92
|
-
parser.isoparse(value)
|
|
93
|
-
return "valueDate"
|
|
94
|
-
except ValueError:
|
|
95
|
-
return "valueText"
|
|
96
|
-
|
|
97
|
-
msg = f"Unknown value type {type(value)}"
|
|
98
|
-
raise FilterError(msg)
|
|
99
|
-
|
|
100
|
-
|
|
101
88
|
def _handle_date(value: Any) -> str:
|
|
102
89
|
if isinstance(value, str):
|
|
103
90
|
try:
|
|
@@ -107,25 +94,22 @@ def _handle_date(value: Any) -> str:
|
|
|
107
94
|
return value
|
|
108
95
|
|
|
109
96
|
|
|
110
|
-
def _equal(field: str, value: Any) ->
|
|
97
|
+
def _equal(field: str, value: Any) -> FilterReturn:
|
|
111
98
|
if value is None:
|
|
112
|
-
return
|
|
113
|
-
return
|
|
99
|
+
return weaviate.classes.query.Filter.by_property(field).is_none(True)
|
|
100
|
+
return weaviate.classes.query.Filter.by_property(field).equal(_handle_date(value))
|
|
114
101
|
|
|
115
102
|
|
|
116
|
-
def _not_equal(field: str, value: Any) ->
|
|
103
|
+
def _not_equal(field: str, value: Any) -> FilterReturn:
|
|
117
104
|
if value is None:
|
|
118
|
-
return
|
|
119
|
-
return {
|
|
120
|
-
"operator": "Or",
|
|
121
|
-
"operands": [
|
|
122
|
-
{"path": field, "operator": "NotEqual", _infer_value_type(value): _handle_date(value)},
|
|
123
|
-
{"path": field, "operator": "IsNull", "valueBoolean": True},
|
|
124
|
-
],
|
|
125
|
-
}
|
|
105
|
+
return weaviate.classes.query.Filter.by_property(field).is_none(False)
|
|
126
106
|
|
|
107
|
+
return weaviate.classes.query.Filter.by_property(field).not_equal(
|
|
108
|
+
_handle_date(value)
|
|
109
|
+
) | weaviate.classes.query.Filter.by_property(field).is_none(True)
|
|
127
110
|
|
|
128
|
-
|
|
111
|
+
|
|
112
|
+
def _greater_than(field: str, value: Any) -> FilterReturn:
|
|
129
113
|
if value is None:
|
|
130
114
|
# When the value is None and '>' is used we create a filter that would return a Document
|
|
131
115
|
# if it has a field set and not set at the same time.
|
|
@@ -144,10 +128,10 @@ def _greater_than(field: str, value: Any) -> Dict[str, Any]:
|
|
|
144
128
|
if type(value) in [list, DataFrame]:
|
|
145
129
|
msg = f"Filter value can't be of type {type(value)} using operators '>', '>=', '<', '<='"
|
|
146
130
|
raise FilterError(msg)
|
|
147
|
-
return
|
|
131
|
+
return weaviate.classes.query.Filter.by_property(field).greater_than(_handle_date(value))
|
|
148
132
|
|
|
149
133
|
|
|
150
|
-
def _greater_than_equal(field: str, value: Any) ->
|
|
134
|
+
def _greater_than_equal(field: str, value: Any) -> FilterReturn:
|
|
151
135
|
if value is None:
|
|
152
136
|
# When the value is None and '>=' is used we create a filter that would return a Document
|
|
153
137
|
# if it has a field set and not set at the same time.
|
|
@@ -166,10 +150,10 @@ def _greater_than_equal(field: str, value: Any) -> Dict[str, Any]:
|
|
|
166
150
|
if type(value) in [list, DataFrame]:
|
|
167
151
|
msg = f"Filter value can't be of type {type(value)} using operators '>', '>=', '<', '<='"
|
|
168
152
|
raise FilterError(msg)
|
|
169
|
-
return
|
|
153
|
+
return weaviate.classes.query.Filter.by_property(field).greater_or_equal(_handle_date(value))
|
|
170
154
|
|
|
171
155
|
|
|
172
|
-
def _less_than(field: str, value: Any) ->
|
|
156
|
+
def _less_than(field: str, value: Any) -> FilterReturn:
|
|
173
157
|
if value is None:
|
|
174
158
|
# When the value is None and '<' is used we create a filter that would return a Document
|
|
175
159
|
# if it has a field set and not set at the same time.
|
|
@@ -188,10 +172,10 @@ def _less_than(field: str, value: Any) -> Dict[str, Any]:
|
|
|
188
172
|
if type(value) in [list, DataFrame]:
|
|
189
173
|
msg = f"Filter value can't be of type {type(value)} using operators '>', '>=', '<', '<='"
|
|
190
174
|
raise FilterError(msg)
|
|
191
|
-
return
|
|
175
|
+
return weaviate.classes.query.Filter.by_property(field).less_than(_handle_date(value))
|
|
192
176
|
|
|
193
177
|
|
|
194
|
-
def _less_than_equal(field: str, value: Any) ->
|
|
178
|
+
def _less_than_equal(field: str, value: Any) -> FilterReturn:
|
|
195
179
|
if value is None:
|
|
196
180
|
# When the value is None and '<=' is used we create a filter that would return a Document
|
|
197
181
|
# if it has a field set and not set at the same time.
|
|
@@ -210,22 +194,23 @@ def _less_than_equal(field: str, value: Any) -> Dict[str, Any]:
|
|
|
210
194
|
if type(value) in [list, DataFrame]:
|
|
211
195
|
msg = f"Filter value can't be of type {type(value)} using operators '>', '>=', '<', '<='"
|
|
212
196
|
raise FilterError(msg)
|
|
213
|
-
return
|
|
197
|
+
return weaviate.classes.query.Filter.by_property(field).less_or_equal(_handle_date(value))
|
|
214
198
|
|
|
215
199
|
|
|
216
|
-
def _in(field: str, value: Any) ->
|
|
200
|
+
def _in(field: str, value: Any) -> FilterReturn:
|
|
217
201
|
if not isinstance(value, list):
|
|
218
202
|
msg = f"{field}'s value must be a list when using 'in' or 'not in' comparators"
|
|
219
203
|
raise FilterError(msg)
|
|
220
204
|
|
|
221
|
-
return
|
|
205
|
+
return weaviate.classes.query.Filter.by_property(field).contains_any(value)
|
|
222
206
|
|
|
223
207
|
|
|
224
|
-
def _not_in(field: str, value: Any) ->
|
|
208
|
+
def _not_in(field: str, value: Any) -> FilterReturn:
|
|
225
209
|
if not isinstance(value, list):
|
|
226
210
|
msg = f"{field}'s value must be a list when using 'in' or 'not in' comparators"
|
|
227
211
|
raise FilterError(msg)
|
|
228
|
-
|
|
212
|
+
operands = [weaviate.classes.query.Filter.by_property(field).not_equal(v) for v in value]
|
|
213
|
+
return Filter.all_of(operands)
|
|
229
214
|
|
|
230
215
|
|
|
231
216
|
COMPARISON_OPERATORS = {
|
|
@@ -240,7 +225,7 @@ COMPARISON_OPERATORS = {
|
|
|
240
225
|
}
|
|
241
226
|
|
|
242
227
|
|
|
243
|
-
def _parse_comparison_condition(condition: Dict[str, Any]) ->
|
|
228
|
+
def _parse_comparison_condition(condition: Dict[str, Any]) -> FilterReturn:
|
|
244
229
|
field: str = condition["field"]
|
|
245
230
|
|
|
246
231
|
if field.startswith("meta."):
|
|
@@ -265,15 +250,11 @@ def _parse_comparison_condition(condition: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
265
250
|
return COMPARISON_OPERATORS[operator](field, value)
|
|
266
251
|
|
|
267
252
|
|
|
268
|
-
def _match_no_document(field: str) ->
|
|
253
|
+
def _match_no_document(field: str) -> FilterReturn:
|
|
269
254
|
"""
|
|
270
255
|
Returns a filters that will match no Document, this is used to keep the behavior consistent
|
|
271
256
|
between different Document Stores.
|
|
272
257
|
"""
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
{"path": field, "operator": "IsNull", "valueBoolean": False},
|
|
277
|
-
{"path": field, "operator": "IsNull", "valueBoolean": True},
|
|
278
|
-
],
|
|
279
|
-
}
|
|
258
|
+
|
|
259
|
+
operands = [weaviate.classes.query.Filter.by_property(field).is_none(val) for val in [False, True]]
|
|
260
|
+
return Filter.all_of(operands)
|