1717
1818from stac_fastapi .core .base_database_logic import BaseDatabaseLogic
1919from 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
2121from stac_fastapi .elasticsearch .config import AsyncElasticsearchSettings
2222from 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