Describe the bug
document_matches_filter raises a FilterError when comparing a string date field in Document.meta against a datetime object using ordering operators (>, >=, <, <=), even though storing dates as ISO strings in metadata is a common and valid pattern.
Error message
FilterError: Can't compare strings using operators '>', '>=', '<', '<='. Strings are only comparable if they are ISO formatted dates.
To Reproduce
from datetime import datetime, timezone
from haystack.dataclasses import Document
from haystack.utils.filters import document_matches_filter
doc = Document(content="test", meta={"date": "2024-01-01"})
filters = {
"field": "meta.date",
"operator": ">",
"value": datetime(2023, 1, 1, tzinfo=timezone.utc)
}
document_matches_filter(filters, doc) # Raises FilterError
Expected behavior
The filter should parse the string operand into a datetime object and perform the comparison successfully.
Root Cause
In haystack/utils/filters.py, _prepare_ordering_comparison calls _parse_date on both operands unconditionally if either is a string. When the other operand is already a datetime object, _parse_date fails because it expects a string input.
Fix
Conditionally call _parse_date only when the operand is actually a string:
value = _parse_date(value) if isinstance(value, str) else value
filter_value = _parse_date(filter_value) if isinstance(filter_value, str) else filter_value
Additionally normalize timezone awareness when both resolve to datetime to prevent TypeError on naive/aware comparisons.
Additional context
Only affects mixed-type comparisons where one operand is a string ISO date and the other is a datetime object. Pure string-to-string and datetime-to-datetime comparisons are unaffected.
System:
- OS: any
- Haystack version: 2.31.0-rc0
- Component:
document_matches_filter, InMemoryDocumentStore, MetadataRouter
Describe the bug
document_matches_filterraises aFilterErrorwhen comparing a string date field inDocument.metaagainst adatetimeobject using ordering operators (>,>=,<,<=), even though storing dates as ISO strings in metadata is a common and valid pattern.Error message
To Reproduce
Expected behavior
The filter should parse the string operand into a
datetimeobject and perform the comparison successfully.Root Cause
In
haystack/utils/filters.py,_prepare_ordering_comparisoncalls_parse_dateon both operands unconditionally if either is a string. When the other operand is already adatetimeobject,_parse_datefails because it expects a string input.Fix
Conditionally call
_parse_dateonly when the operand is actually a string:Additionally normalize timezone awareness when both resolve to
datetimeto preventTypeErroron naive/aware comparisons.Additional context
Only affects mixed-type comparisons where one operand is a string ISO date and the other is a
datetimeobject. Pure string-to-string and datetime-to-datetime comparisons are unaffected.System:
document_matches_filter,InMemoryDocumentStore,MetadataRouter