From 70ac35b2a5b0640e6ebc6ceacd04ae7fdd32ad95 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Thu, 14 Jul 2022 18:20:09 +0400 Subject: [PATCH] Compute Date Range to filter entries to, from Comparators, Dates in Query --- src/search_filter/date_filter.py | 44 ++++++++++++++++++++++++++++++++ tests/test_date_filter.py | 14 +++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/search_filter/date_filter.py b/src/search_filter/date_filter.py index fe7ee5e5..b1c2cadc 100644 --- a/src/search_filter/date_filter.py +++ b/src/search_filter/date_filter.py @@ -45,6 +45,50 @@ def date_filter(query, entries, embeddings): return query, entries, embeddings + +def extract_date_range(query): + # find date range filter in query + date_range_match = re.search(date_range_regex, query) + if not date_range_match or date_range_match.groups() == (None, None, None, None): + return None + + # extract, parse natural dates ranges from date range filter passed in query + # e.g today maps to (start_of_day, start_of_tomorrow) + query_dtranges = [] + for date_str in date_range_match.groups()[1::2]: + if date_str and parse(date_str): + dt_start, dt_end = parse(date_str) + query_dtranges.append((dt_start.timestamp(), dt_end.timestamp())) + + date_comparators = [date_cmp for date_cmp in date_range_match.groups()[0::2] if date_cmp] + + # Combine dates with their comparators to form date range intervals + # For e.g + # >=yesterday maps to [start_of_yesterday, inf) + # ' and dtrange_end < effective_date_range[1]: + effective_date_range[0] = dtrange_end + elif cmp == '<' and dtrange_start > effective_date_range[0]: + effective_date_range[1] = dtrange_start + elif cmp == '>=' and dtrange_end < effective_date_range[1]: + effective_date_range[0] = dtrange_start + elif cmp == '<=' and dtrange_start > effective_date_range[0]: + effective_date_range[1] = dtrange_end + elif cmp == '=' or cmp == ':' or cmp == '==': + effective_date_range = [dtrange_start, dtrange_end] + + if effective_date_range == [0, inf]: + return None + else: + return effective_date_range + + def parse(date_str, relative_base=None): "Parse date string passed in date filter of query to datetime object" # clean date string to handle future date parsing by date parser diff --git a/tests/test_date_filter.py b/tests/test_date_filter.py index 8abec3af..76dad113 100644 --- a/tests/test_date_filter.py +++ b/tests/test_date_filter.py @@ -1,10 +1,22 @@ # Standard Packages import re -from datetime import timedelta, datetime +from datetime import datetime +from math import inf # Application Packages from src.search_filter import date_filter + +def test_extract_date_range(): + assert date_filter.extract_date_range('head dt>"2020-01-04" dt<"2020-01-07" tail') == [datetime(2020, 1, 5, 0, 0, 0).timestamp(), datetime(2020, 1, 7, 0, 0, 0).timestamp()] + assert date_filter.extract_date_range('head dt<="2020-01-01"') == [0, datetime(2020, 1, 2, 0, 0, 0).timestamp()] + assert date_filter.extract_date_range('head dt>="2020-01-01"') == [datetime(2020, 1, 1, 0, 0, 0).timestamp(), inf] + assert date_filter.extract_date_range('head dt:"2020-01-01"') == [datetime(2020, 1, 1, 0, 0, 0).timestamp(), datetime(2020, 1, 2, 0, 0, 0).timestamp()] + + # No date filter specified in query + assert date_filter.extract_date_range('head tail') == None + + def test_parse(): test_now = datetime(1984, 4, 1, 21, 21, 21)