Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions redisvl/query/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,13 +803,22 @@ def __ne__(
self: The filter object for method chaining
"""
if self._is_date(other):
# For date objects, exclude the entire day
# For date objects, exclude the entire day by negating exactly the
# range that __eq__ matches.
if isinstance(other, str):
other = datetime.datetime.strptime(other, "%Y-%m-%d").date()
assert isinstance(other, datetime.date) # validate for mypy
start = datetime.datetime.combine(other, datetime.time.min)
end = datetime.datetime.combine(other, datetime.time.max)
return self.between(start, end)
start = datetime.datetime.combine(other, datetime.time.min).astimezone(
datetime.timezone.utc
)
end = datetime.datetime.combine(other, datetime.time.max).astimezone(
datetime.timezone.utc
)
start_ts = self._convert_to_timestamp(start)
end_ts = self._convert_to_timestamp(end, end_date=True)
return FilterExpression(
self.OPERATOR_MAP[FilterOperator.NE] % (self._field, start_ts, end_ts)
)

timestamp = self._convert_to_timestamp(other)
self._set_value(timestamp, self.SUPPORTED_TYPES, FilterOperator.NE)
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/test_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,26 @@ def test_timestamp_date():
assert str(ts) == f"@created_at:[{expected_ts_start} {expected_ts_end}]"


def test_timestamp_not_equal_date():
"""Test Timestamp != with date objects (should exclude the full day)."""
d = date(2023, 3, 17)
ts = Timestamp("created_at") != d

expected_ts_start = (
datetime.combine(d, time.min).astimezone(timezone.utc).timestamp()
)
expected_ts_end = datetime.combine(d, time.max).astimezone(timezone.utc).timestamp()

assert str(ts) == f"(-@created_at:[{expected_ts_start} {expected_ts_end}])"

# != must be the exact negation of == for the same date
eq = Timestamp("created_at") == d
assert str(ts) == f"(-{eq!s})"

# A date-only ISO string takes the same path as a date object
assert str(Timestamp("created_at") != "2023-03-17") == str(ts)


def test_timestamp_iso_string():
"""Test Timestamp filter with ISO format strings."""
# Date-only ISO string
Expand Down