| 
16 | 16 | 
 
  | 
17 | 17 | from stac_fastapi.core.base_database_logic import BaseDatabaseLogic  | 
18 | 18 | 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  | 
20 | 20 | from stac_fastapi.extensions.core.transaction.request import (  | 
21 | 21 |     PartialCollection,  | 
22 | 22 |     PartialItem,  | 
@@ -301,75 +301,93 @@ def apply_datetime_filter(  | 
301 | 301 |         if not datetime_search:  | 
302 | 302 |             return search, datetime_search  | 
303 | 303 | 
 
  | 
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(  | 
310 |  | -                    "bool",  | 
311 |  | -                    filter=[  | 
312 |  | -                        Q("exists", field="properties.datetime"),  | 
313 |  | -                        Q("term", **{"properties__datetime": datetime_search["eq"]}),  | 
314 |  | -                    ],  | 
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(  | 
339 |  | -                    "bool",  | 
340 |  | -                    filter=[  | 
341 |  | -                        Q("exists", field="properties.datetime"),  | 
342 |  | -                        Q(  | 
343 |  | -                            "range",  | 
344 |  | -                            properties__datetime={  | 
345 |  | -                                "gte": datetime_search["gte"],  | 
346 |  | -                                "lte": datetime_search["lte"],  | 
347 |  | -                            },  | 
348 |  | -                        ),  | 
349 |  | -                    ],  | 
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 |  | -            ]  | 
 | 304 | +        # USE_DATETIME env var  | 
 | 305 | +        # True: Search by datetime, if null search by start/end datetime  | 
 | 306 | +        # False: Always search only by start/end datetime  | 
 | 307 | +        USE_DATETIME = get_bool_env("USE_DATETIME", default=True)  | 
 | 308 | + | 
 | 309 | +        if USE_DATETIME:  | 
 | 310 | +            if "eq" in datetime_search:  | 
 | 311 | +                # For exact matches, include:  | 
 | 312 | +                # 1. Items with matching exact datetime  | 
 | 313 | +                # 2. Items with datetime:null where the time falls within their range  | 
 | 314 | +                should = [  | 
 | 315 | +                    Q(  | 
 | 316 | +                        "bool",  | 
 | 317 | +                        filter=[  | 
 | 318 | +                            Q("exists", field="properties.datetime"),  | 
 | 319 | +                            Q(  | 
 | 320 | +                                "term",  | 
 | 321 | +                                **{"properties__datetime": datetime_search["eq"]},  | 
 | 322 | +                            ),  | 
 | 323 | +                        ],  | 
 | 324 | +                    ),  | 
 | 325 | +                    Q(  | 
 | 326 | +                        "bool",  | 
 | 327 | +                        must_not=[Q("exists", field="properties.datetime")],  | 
 | 328 | +                        filter=[  | 
 | 329 | +                            Q("exists", field="properties.start_datetime"),  | 
 | 330 | +                            Q("exists", field="properties.end_datetime"),  | 
 | 331 | +                            Q(  | 
 | 332 | +                                "range",  | 
 | 333 | +                                properties__start_datetime={  | 
 | 334 | +                                    "lte": datetime_search["eq"]  | 
 | 335 | +                                },  | 
 | 336 | +                            ),  | 
 | 337 | +                            Q(  | 
 | 338 | +                                "range",  | 
 | 339 | +                                properties__end_datetime={"gte": datetime_search["eq"]},  | 
 | 340 | +                            ),  | 
 | 341 | +                        ],  | 
 | 342 | +                    ),  | 
 | 343 | +                ]  | 
 | 344 | +            else:  | 
 | 345 | +                # For date ranges, include:  | 
 | 346 | +                # 1. Items with datetime in the range  | 
 | 347 | +                # 2. Items with datetime:null that overlap the search range  | 
 | 348 | +                should = [  | 
 | 349 | +                    Q(  | 
 | 350 | +                        "bool",  | 
 | 351 | +                        filter=[  | 
 | 352 | +                            Q("exists", field="properties.datetime"),  | 
 | 353 | +                            Q(  | 
 | 354 | +                                "range",  | 
 | 355 | +                                properties__datetime={  | 
 | 356 | +                                    "gte": datetime_search["gte"],  | 
 | 357 | +                                    "lte": datetime_search["lte"],  | 
 | 358 | +                                },  | 
 | 359 | +                            ),  | 
 | 360 | +                        ],  | 
 | 361 | +                    ),  | 
 | 362 | +                    Q(  | 
 | 363 | +                        "bool",  | 
 | 364 | +                        must_not=[Q("exists", field="properties.datetime")],  | 
 | 365 | +                        filter=[  | 
 | 366 | +                            Q("exists", field="properties.start_datetime"),  | 
 | 367 | +                            Q("exists", field="properties.end_datetime"),  | 
 | 368 | +                            Q(  | 
 | 369 | +                                "range",  | 
 | 370 | +                                properties__start_datetime={  | 
 | 371 | +                                    "lte": datetime_search["lte"]  | 
 | 372 | +                                },  | 
 | 373 | +                            ),  | 
 | 374 | +                            Q(  | 
 | 375 | +                                "range",  | 
 | 376 | +                                properties__end_datetime={  | 
 | 377 | +                                    "gte": datetime_search["gte"]  | 
 | 378 | +                                },  | 
 | 379 | +                            ),  | 
 | 380 | +                        ],  | 
 | 381 | +                    ),  | 
 | 382 | +                ]  | 
 | 383 | + | 
 | 384 | +            return (  | 
 | 385 | +                search.query(Q("bool", should=should, minimum_should_match=1)),  | 
 | 386 | +                datetime_search,  | 
 | 387 | +            )  | 
368 | 388 | 
 
  | 
369 |  | -        return (  | 
370 |  | -            search.query(Q("bool", should=should, minimum_should_match=1)),  | 
371 |  | -            datetime_search,  | 
372 |  | -        )  | 
 | 389 | +        # If USE_DATETIME is False, return the original search unchanged  | 
 | 390 | +        return search, datetime_search  | 
373 | 391 | 
 
  | 
374 | 392 |     @staticmethod  | 
375 | 393 |     def apply_bbox_filter(search: Search, bbox: List):  | 
 | 
0 commit comments