Skip to content

Commit 4fec6e1

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 only filter on properties.datetime field, ignoring start/end datetime fields - USE_DATETIME=False (default): Use existing logic that handles both datetime and start/end datetime fields
1 parent ca26c0a commit 4fec6e1

File tree

1 file changed

+90
-54
lines changed

1 file changed

+90
-54
lines changed

stac_fastapi/opensearch/stac_fastapi/opensearch/database_logic.py

Lines changed: 90 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
1818
from stac_fastapi.core.serializers import CollectionSerializer, ItemSerializer
19-
from stac_fastapi.core.utilities import bbox2polygon, get_max_limit
19+
from stac_fastapi.core.utilities import bbox2polygon, get_bool_env, get_max_limit
2020
from stac_fastapi.extensions.core.transaction.request import (
2121
PartialCollection,
2222
PartialItem,
@@ -301,41 +301,22 @@ def apply_datetime_filter(
301301
if not datetime_search:
302302
return search, datetime_search
303303

304-
if "eq" in datetime_search:
305-
# For exact matches, include:
306-
# 1. Items with matching exact datetime
307-
# 2. Items with datetime:null where the time falls within their range
308-
should = [
309-
Q(
304+
# USE_DATETIME env var
305+
# True: Only search by datetime and ignore start/end datetime
306+
# False: Search by datetime, if null search by start/end datetime
307+
USE_DATETIME = get_bool_env("USE_DATETIME", default=False)
308+
309+
if USE_DATETIME:
310+
if "eq" in datetime_search:
311+
filter_query = Q(
310312
"bool",
311313
filter=[
312314
Q("exists", field="properties.datetime"),
313315
Q("term", **{"properties__datetime": datetime_search["eq"]}),
314316
],
315-
),
316-
Q(
317-
"bool",
318-
must_not=[Q("exists", field="properties.datetime")],
319-
filter=[
320-
Q("exists", field="properties.start_datetime"),
321-
Q("exists", field="properties.end_datetime"),
322-
Q(
323-
"range",
324-
properties__start_datetime={"lte": datetime_search["eq"]},
325-
),
326-
Q(
327-
"range",
328-
properties__end_datetime={"gte": datetime_search["eq"]},
329-
),
330-
],
331-
),
332-
]
333-
else:
334-
# For date ranges, include:
335-
# 1. Items with datetime in the range
336-
# 2. Items with datetime:null that overlap the search range
337-
should = [
338-
Q(
317+
)
318+
else:
319+
filter_query = Q(
339320
"bool",
340321
filter=[
341322
Q("exists", field="properties.datetime"),
@@ -347,29 +328,84 @@ def apply_datetime_filter(
347328
},
348329
),
349330
],
350-
),
351-
Q(
352-
"bool",
353-
must_not=[Q("exists", field="properties.datetime")],
354-
filter=[
355-
Q("exists", field="properties.start_datetime"),
356-
Q("exists", field="properties.end_datetime"),
357-
Q(
358-
"range",
359-
properties__start_datetime={"lte": datetime_search["lte"]},
360-
),
361-
Q(
362-
"range",
363-
properties__end_datetime={"gte": datetime_search["gte"]},
364-
),
365-
],
366-
),
367-
]
368-
369-
return (
370-
search.query(Q("bool", should=should, minimum_should_match=1)),
371-
datetime_search,
372-
)
331+
)
332+
return search.query(filter_query), datetime_search
333+
else:
334+
if "eq" in datetime_search:
335+
should = [
336+
Q(
337+
"bool",
338+
filter=[
339+
Q("exists", field="properties.datetime"),
340+
Q(
341+
"term",
342+
**{"properties__datetime": datetime_search["eq"]},
343+
),
344+
],
345+
),
346+
Q(
347+
"bool",
348+
must_not=[Q("exists", field="properties.datetime")],
349+
filter=[
350+
Q("exists", field="properties.start_datetime"),
351+
Q("exists", field="properties.end_datetime"),
352+
Q(
353+
"range",
354+
properties__start_datetime={
355+
"lte": datetime_search["eq"]
356+
},
357+
),
358+
Q(
359+
"range",
360+
properties__end_datetime={"gte": datetime_search["eq"]},
361+
),
362+
],
363+
),
364+
]
365+
else:
366+
# For date ranges, include:
367+
# 1. Items with datetime in the range
368+
# 2. Items with datetime:null that overlap the search range
369+
should = [
370+
Q(
371+
"bool",
372+
filter=[
373+
Q("exists", field="properties.datetime"),
374+
Q(
375+
"range",
376+
properties__datetime={
377+
"gte": datetime_search["gte"],
378+
"lte": datetime_search["lte"],
379+
},
380+
),
381+
],
382+
),
383+
Q(
384+
"bool",
385+
must_not=[Q("exists", field="properties.datetime")],
386+
filter=[
387+
Q("exists", field="properties.start_datetime"),
388+
Q("exists", field="properties.end_datetime"),
389+
Q(
390+
"range",
391+
properties__start_datetime={
392+
"lte": datetime_search["lte"]
393+
},
394+
),
395+
Q(
396+
"range",
397+
properties__end_datetime={
398+
"gte": datetime_search["gte"]
399+
},
400+
),
401+
],
402+
),
403+
]
404+
405+
return (
406+
search.query(Q("bool", should=should, minimum_should_match=1)),
407+
datetime_search,
408+
)
373409

374410
@staticmethod
375411
def apply_bbox_filter(search: Search, bbox: List):

0 commit comments

Comments
 (0)