Skip to content

Commit 61cf079

Browse files
Yuri ZmytrakovYuri Zmytrakov
authored andcommitted
feat: use_datetime env var to modify search
- Added USE_DATETIME env var to control datetime filtering - USE_DATETIME=True (default): use existing logic that handles both datetime and start/end datetime fields - USE_DATETIME=False (default): use only start/end datetime fields for search
1 parent c5471c1 commit 61cf079

File tree

2 files changed

+364
-221
lines changed

2 files changed

+364
-221
lines changed

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
1919
from stac_fastapi.core.serializers import CollectionSerializer, ItemSerializer
20-
from stac_fastapi.core.utilities import bbox2polygon, get_max_limit
20+
from stac_fastapi.core.utilities import bbox2polygon, get_bool_env, get_max_limit
2121
from stac_fastapi.elasticsearch.config import AsyncElasticsearchSettings
2222
from stac_fastapi.elasticsearch.config import (
2323
ElasticsearchSettings as SyncElasticsearchSettings,
@@ -289,26 +289,99 @@ def apply_datetime_filter(
289289
Returns:
290290
The filtered search object.
291291
"""
292+
# USE_DATETIME env var
293+
# True: Search by datetime, if null search by start/end datetime
294+
# False: Always search only by start/end datetime
295+
USE_DATETIME = get_bool_env("USE_DATETIME", default=True)
296+
292297
datetime_search = return_date(datetime)
293298

294299
if not datetime_search:
295300
return search, datetime_search
296301

297-
if "eq" in datetime_search:
298-
# For exact matches, include:
299-
# 1. Items with matching exact datetime
300-
# 2. Items with datetime:null where the time falls within their range
301-
should = [
302-
Q(
303-
"bool",
304-
filter=[
305-
Q("exists", field="properties.datetime"),
306-
Q("term", **{"properties__datetime": datetime_search["eq"]}),
307-
],
308-
),
309-
Q(
302+
if USE_DATETIME:
303+
if "eq" in datetime_search:
304+
# For exact matches, include:
305+
# 1. Items with matching exact datetime
306+
# 2. Items with datetime:null where the time falls within their range
307+
should = [
308+
Q(
309+
"bool",
310+
filter=[
311+
Q("exists", field="properties.datetime"),
312+
Q(
313+
"term",
314+
**{"properties__datetime": datetime_search["eq"]},
315+
),
316+
],
317+
),
318+
Q(
319+
"bool",
320+
must_not=[Q("exists", field="properties.datetime")],
321+
filter=[
322+
Q("exists", field="properties.start_datetime"),
323+
Q("exists", field="properties.end_datetime"),
324+
Q(
325+
"range",
326+
properties__start_datetime={
327+
"lte": datetime_search["eq"]
328+
},
329+
),
330+
Q(
331+
"range",
332+
properties__end_datetime={"gte": datetime_search["eq"]},
333+
),
334+
],
335+
),
336+
]
337+
else:
338+
# For date ranges, include:
339+
# 1. Items with datetime in the range
340+
# 2. Items with datetime:null that overlap the search range
341+
should = [
342+
Q(
343+
"bool",
344+
filter=[
345+
Q("exists", field="properties.datetime"),
346+
Q(
347+
"range",
348+
properties__datetime={
349+
"gte": datetime_search["gte"],
350+
"lte": datetime_search["lte"],
351+
},
352+
),
353+
],
354+
),
355+
Q(
356+
"bool",
357+
must_not=[Q("exists", field="properties.datetime")],
358+
filter=[
359+
Q("exists", field="properties.start_datetime"),
360+
Q("exists", field="properties.end_datetime"),
361+
Q(
362+
"range",
363+
properties__start_datetime={
364+
"lte": datetime_search["lte"]
365+
},
366+
),
367+
Q(
368+
"range",
369+
properties__end_datetime={
370+
"gte": datetime_search["gte"]
371+
},
372+
),
373+
],
374+
),
375+
]
376+
377+
return (
378+
search.query(Q("bool", should=should, minimum_should_match=1)),
379+
datetime_search,
380+
)
381+
else:
382+
if "eq" in datetime_search:
383+
filter_query = Q(
310384
"bool",
311-
must_not=[Q("exists", field="properties.datetime")],
312385
filter=[
313386
Q("exists", field="properties.start_datetime"),
314387
Q("exists", field="properties.end_datetime"),
@@ -321,29 +394,10 @@ def apply_datetime_filter(
321394
properties__end_datetime={"gte": datetime_search["eq"]},
322395
),
323396
],
324-
),
325-
]
326-
else:
327-
# For date ranges, include:
328-
# 1. Items with datetime in the range
329-
# 2. Items with datetime:null that overlap the search range
330-
should = [
331-
Q(
332-
"bool",
333-
filter=[
334-
Q("exists", field="properties.datetime"),
335-
Q(
336-
"range",
337-
properties__datetime={
338-
"gte": datetime_search["gte"],
339-
"lte": datetime_search["lte"],
340-
},
341-
),
342-
],
343-
),
344-
Q(
397+
)
398+
else:
399+
filter_query = Q(
345400
"bool",
346-
must_not=[Q("exists", field="properties.datetime")],
347401
filter=[
348402
Q("exists", field="properties.start_datetime"),
349403
Q("exists", field="properties.end_datetime"),
@@ -356,13 +410,8 @@ def apply_datetime_filter(
356410
properties__end_datetime={"gte": datetime_search["gte"]},
357411
),
358412
],
359-
),
360-
]
361-
362-
return (
363-
search.query(Q("bool", should=should, minimum_should_match=1)),
364-
datetime_search,
365-
)
413+
)
414+
return search.query(filter_query), datetime_search
366415

367416
@staticmethod
368417
def apply_bbox_filter(search: Search, bbox: List):

0 commit comments

Comments
 (0)