11"""Database logic."""
2-
32import asyncio
43import logging
54from base64 import urlsafe_b64decode , urlsafe_b64encode
1615
1716from stac_fastapi .core .base_database_logic import BaseDatabaseLogic
1817from stac_fastapi .core .serializers import CollectionSerializer , ItemSerializer
19- from stac_fastapi .core .utilities import MAX_LIMIT , bbox2polygon
18+ from stac_fastapi .core .utilities import MAX_LIMIT , bbox2polygon , get_bool_env
2019from stac_fastapi .extensions .core .transaction .request import (
2120 PartialCollection ,
2221 PartialItem ,
@@ -301,41 +300,22 @@ def apply_datetime_filter(
301300 if not datetime_search :
302301 return search , datetime_search
303302
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 (
303+ # USE_DATETIME env var
304+ # True: Only search by datetime and ignore start/end datetime
305+ # False: Search by datetime, if null search by start/end datetime
306+ USE_DATETIME = get_bool_env ("USE_DATETIME" , default = False )
307+
308+ if USE_DATETIME :
309+ if "eq" in datetime_search :
310+ filter_query = Q (
310311 "bool" ,
311312 filter = [
312313 Q ("exists" , field = "properties.datetime" ),
313314 Q ("term" , ** {"properties__datetime" : datetime_search ["eq" ]}),
314315 ],
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 (
316+ )
317+ else :
318+ filter_query = Q (
339319 "bool" ,
340320 filter = [
341321 Q ("exists" , field = "properties.datetime" ),
@@ -347,29 +327,84 @@ def apply_datetime_filter(
347327 },
348328 ),
349329 ],
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- )
330+ )
331+ return search .query (filter_query ), datetime_search
332+ else :
333+ if "eq" in datetime_search :
334+ should = [
335+ Q (
336+ "bool" ,
337+ filter = [
338+ Q ("exists" , field = "properties.datetime" ),
339+ Q (
340+ "term" ,
341+ ** {"properties__datetime" : datetime_search ["eq" ]},
342+ ),
343+ ],
344+ ),
345+ Q (
346+ "bool" ,
347+ must_not = [Q ("exists" , field = "properties.datetime" )],
348+ filter = [
349+ Q ("exists" , field = "properties.start_datetime" ),
350+ Q ("exists" , field = "properties.end_datetime" ),
351+ Q (
352+ "range" ,
353+ properties__start_datetime = {
354+ "lte" : datetime_search ["eq" ]
355+ },
356+ ),
357+ Q (
358+ "range" ,
359+ properties__end_datetime = {"gte" : datetime_search ["eq" ]},
360+ ),
361+ ],
362+ ),
363+ ]
364+ else :
365+ # For date ranges, include:
366+ # 1. Items with datetime in the range
367+ # 2. Items with datetime:null that overlap the search range
368+ should = [
369+ Q (
370+ "bool" ,
371+ filter = [
372+ Q ("exists" , field = "properties.datetime" ),
373+ Q (
374+ "range" ,
375+ properties__datetime = {
376+ "gte" : datetime_search ["gte" ],
377+ "lte" : datetime_search ["lte" ],
378+ },
379+ ),
380+ ],
381+ ),
382+ Q (
383+ "bool" ,
384+ must_not = [Q ("exists" , field = "properties.datetime" )],
385+ filter = [
386+ Q ("exists" , field = "properties.start_datetime" ),
387+ Q ("exists" , field = "properties.end_datetime" ),
388+ Q (
389+ "range" ,
390+ properties__start_datetime = {
391+ "lte" : datetime_search ["lte" ]
392+ },
393+ ),
394+ Q (
395+ "range" ,
396+ properties__end_datetime = {
397+ "gte" : datetime_search ["gte" ]
398+ },
399+ ),
400+ ],
401+ ),
402+ ]
403+
404+ return (
405+ search .query (Q ("bool" , should = should , minimum_should_match = 1 )),
406+ datetime_search ,
407+ )
373408
374409 @staticmethod
375410 def apply_bbox_filter (search : Search , bbox : List ):
0 commit comments