Skip to content

Commit 6f786af

Browse files
fix: handle non-dict intermediate value in nested metadata filters (#11649)
1 parent 141b7d7 commit 6f786af

3 files changed

Lines changed: 23 additions & 2 deletions

File tree

haystack/utils/filters.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ def _comparison_condition(condition: dict[str, Any], document: Document | ByteSt
195195
parts = field.split(".")
196196
document_value = getattr(document, parts[0])
197197
for part in parts[1:]:
198-
if part not in document_value:
199-
# If a field is not found we treat it as None
198+
if not isinstance(document_value, dict) or part not in document_value:
199+
# If a field is not found (or an intermediate value is not a dict,
200+
# e.g. None) we treat it as None
200201
document_value = None
201202
break
202203
document_value = document_value[part]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
fixes:
3+
- |
4+
Fixed a ``TypeError`` when filtering documents on a nested metadata field
5+
(e.g. ``meta.user.age``) where an intermediate value is not a dictionary
6+
(for example ``None`` or a scalar). Such intermediate values are now treated
7+
as a missing field (``None``) instead of raising, which previously crashed
8+
``filter_documents`` for stores like ``InMemoryDocumentStore``.

test/utils/test_filters.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@
4646
False,
4747
id="== operator with None filter value",
4848
),
49+
pytest.param(
50+
{"field": "meta.user.age", "operator": "==", "value": 30},
51+
Document(meta={"user": {"age": 30}}),
52+
True,
53+
id="== operator with nested meta field",
54+
),
55+
pytest.param(
56+
{"field": "meta.user.age", "operator": "==", "value": 30},
57+
Document(meta={"user": None}),
58+
False,
59+
id="== operator with nested field on non-dict intermediate value",
60+
),
4961
# != operator params
5062
pytest.param(
5163
{"field": "meta.name", "operator": "!=", "value": "test"},

0 commit comments

Comments
 (0)