Closed shankari closed 5 years ago
So the mapping for standard queries is
start_val <= field <= end_val
so the queries for the examples above will be:
2015-08-01T08:18 -> 2015-08-02T08:20
:
(2015 <= year <= 2015)
&(8 <= month <= 8)
& (1 <= day <= 2)
& (8 <= hour <= 9)
& (18 <= minute <= 20)
2015-08 08:18 -> 2015-09 09:30
(2015 <= year <= 2015)
&(8 <= month <= 9)
& (8 <= hour <= 9)
& (18 <= minute <= 20)
2015 Tuesday -> 2016 Thursday
(2015 <= year <= 2016)
&(Tuesday <= weekday <= Thursday)
For rollover queries, we need to query across two disjoint sets, so
start_val <= field <= range_max | range_min <= field <= end_val
So this would become:
2015-08-01T08:18 -> 2015-08-02T09:08
:
(2015 <= year <= 2015)
&(8 <= month <= 8)
& (1 <= day <= 2)
& (8 <= hour <= 9)
& (18 <= minute <= 60 | 0 <= minute <= 8)
2015-11 22:40 -> 2016-02 06:10
:
(2015 <= year <= 2016)
&(11 <= month <= 12 | 0 <= month <= 2
& (22 <= hour <= 24 | 0 <= hour <= 6)
& (40 <= minute <= 60 | 0 <= minute <= 8)
2015 Saturday -> 2016 Monday
:
(2015 <= year <= 2016)
&Note that all the components except the year can roll over. Years can never roll over - they are monotonically increasing.
We can also use negation of the non-matched set
not end_val < field < start_val
So this would become:
2015-08-01T08:18 -> 2015-08-02T09:08
:
(2015 <= year <= 2015)
&(8 <= month <= 8)
& (1 <= day <= 2)
& (8 <= hour <= 9)
& not (8 < minute < 18)
2015-11 22:40 -> 2016-02 06:10
:
(2015 <= year <= 2016)
¬ (2 < month < 11)
& not (06 < hour < 22)
& not (10 < minute < 40)
2015 Saturday -> 2016 Monday
:
(2015 <= year <= 2016)
¬ (Mon < weekday < Sat)
The formulation with the negation exposes an important issue with the standard queries as well. They are only applicable for the ends of the range - the middle of the range must not be filtered.
To pick some concrete examples:
2014-02-10 -> 2016-05-15
should include all of 2015, even Jan, June and July2014-02-10 -> 2014-05-15
should include all of Mar and Apr, even days 1-10 and 15-30This will not be matched even by the standard query since the queries will be:
2014-02-10 -> 2016-05-15
: (2014 <= year <= 2016) & (2 <= month <= 5) & (10 <= 15)
This will only match 5 days (10-15) in Feb, Mar, Apr, May, even in the year 2015
wrt the previous comment, it is actually unclear whether the middle of the range should be filtered or not.
Basically, if I see something like 2014-02-10 -> 2016-05-15
, it can be interpreted either as a set of filters on the various year(s) (year = 2014-2015, month = 2-5, day = 10-15) or as a range (10 Feb 2014 to 15 May 2016).
The notion of treating it as filters instead of a range is particularly attractive/important from the aggregate urban planning perspective so that I can look at changes in particular time slices over longer time frames.
The real problem is that we do not have a clear separation between range-based and filter-based queries. Years can only really be range-based, but the other components can be either range-based or filter based as we saw above.
Let's define that the semantics favor filtering since that makes our life easier. We should fix the filtering for rollover as described earlier in this issue.
Later, we can switch to a better design that allows flexibility in choosing range or filter queries
This focus on filtering has some weird implications
2015-08-01T08:18 -> 2015-08-02T09:08
will match not just {'hour': 8, 'minute': 18}
but also {'hour': 9, 'minute': 57}
but for the currently most broken case of the change of month, when the default search is
2016-03-31
to 2016-04-01
we will be fine because in general 2016-04-31
will not have occurred at the time of the query
query is:
DEBUG:root:In get_range_query
returning query {'data.local_dt.minute': {'$not': {'$gt': 8, '$lt': 18}}
'data.local_dt.hour': {'$lte': 9, '$gte': 8}
'data.local_dt.year': {'$lte': 2015, '$gte': 2015}
'data.local_dt.month': {'$lte': 8, '$gte': 8}}
It is not clear that there are any bugs left. We could enhance/change the way the filters actually work, but that's an enhancement, not a bug. Closing this issue for now.
Back in 6753c223c7084f88c9bebdbc6aa9b9e5a8a6ec7a, we implemented the
Localdate
date data structure and queries on it. The queries allow users to fill in fields of a start and end local dt, and we look for entries that are between the start and the end date.This works well for standard queries e.g.
2015-08-01T08:18 -> 2015-08-02T08:20
but it does not work well for rollover queries e.g.
2015-08-01T08:18 -> 2015-08-02T09:08
because when we query for entries where18 <= minute <= 8
, we don't find anyOne option is to convert them to ranges instead, but also that the queries support wildcards, which makes converting them to ranges difficult. So for example, all of the following are valid:
2015-08 08:18 -> 2015-09 09:30
: the range from 8:18 to 9:30 on any day in the months of August and September2015 Tuesday -> 2016 Thursday
: Tue, Wed and Thu in 2015 and 2016Similarly, the following rollover queries are also valid and must be supported:
2015-11 22:40 -> 2016-02 06:10
: the range from 10:40pm to 6:10am on any day in the months of November, December, January or February2015 Saturday -> 2016 Monday
: Sat, Sun and Mon in 2015 and 2016