Skip to content
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added DELETE `/catalogs/{catalog_id}/collections/{collection_id}` endpoint to support removing collections from catalogs. When a collection belongs to multiple catalogs, it removes only the specified catalog from the collection's parent_ids. When a collection belongs to only one catalog, the collection is deleted entirely. [#554](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/554)
- Added `parent_ids` internal field to collections to support multi-catalog hierarchies. Collections can now belong to multiple catalogs, with parent catalog IDs stored in this field for efficient querying and management. [#554](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/554)


### Changed

- Have opensearch datetime, geometry and collections fields defined as constant strings [#553](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/553)

### Fixed

- Fix unawaited coroutine in `stac_fastapi.core.core`. [#551](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/551)
Expand Down
61 changes: 47 additions & 14 deletions stac_fastapi/opensearch/stac_fastapi/opensearch/database_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ def __attrs_post_init__(self):

aggregation_mapping: Dict[str, Dict[str, Any]] = AGGREGATION_MAPPING

# constants for field names
# they are used in multiple methods
# and could be overwritten in subclasses used with alternate opensearch mappings.
PROPERTIES_DATETIME_FIELD = "properties.datetime"
PROPERTIES_START_DATETIME_FIELD = "properties.start_datetime"
PROPERTIES_END_DATETIME_FIELD = "properties.end_datetime"
COLLECTION_FIELD = "collection"
GEOMETRY_FIELD = "geometry"

"""CORE LOGIC"""

async def get_all_collections(
Expand Down Expand Up @@ -436,7 +445,9 @@ def apply_ids_filter(search: Search, item_ids: List[str]):
@staticmethod
def apply_collections_filter(search: Search, collection_ids: List[str]):
"""Database logic to search a list of STAC collection ids."""
return search.filter("terms", collection=collection_ids)
return search.filter(
"terms", **{DatabaseLogic.COLLECTION_FIELD: collection_ids}
)

@staticmethod
def apply_free_text_filter(search: Search, free_text_queries: Optional[List[str]]):
Expand Down Expand Up @@ -488,7 +499,7 @@ def apply_datetime_filter(
Q(
"bool",
filter=[
Q("exists", field="properties.datetime"),
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD),
Q(
"term",
**{"properties__datetime": datetime_search["eq"]},
Expand All @@ -497,10 +508,18 @@ def apply_datetime_filter(
),
Q(
"bool",
must_not=[Q("exists", field="properties.datetime")],
must_not=[
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD)
],
filter=[
Q("exists", field="properties.start_datetime"),
Q("exists", field="properties.end_datetime"),
Q(
"exists",
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
),
Q(
"exists",
field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD,
),
Q(
"range",
properties__start_datetime={
Expand All @@ -522,7 +541,7 @@ def apply_datetime_filter(
Q(
"bool",
filter=[
Q("exists", field="properties.datetime"),
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD),
Q(
"range",
properties__datetime={
Expand All @@ -534,10 +553,18 @@ def apply_datetime_filter(
),
Q(
"bool",
must_not=[Q("exists", field="properties.datetime")],
must_not=[
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD)
],
filter=[
Q("exists", field="properties.start_datetime"),
Q("exists", field="properties.end_datetime"),
Q(
"exists",
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
),
Q(
"exists",
field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD,
),
Q(
"range",
properties__start_datetime={
Expand All @@ -563,8 +590,11 @@ def apply_datetime_filter(
filter_query = Q(
"bool",
filter=[
Q("exists", field="properties.start_datetime"),
Q("exists", field="properties.end_datetime"),
Q(
"exists",
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
),
Q("exists", field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD),
Q(
"range",
properties__start_datetime={"lte": datetime_search["eq"]},
Expand All @@ -579,8 +609,11 @@ def apply_datetime_filter(
filter_query = Q(
"bool",
filter=[
Q("exists", field="properties.start_datetime"),
Q("exists", field="properties.end_datetime"),
Q(
"exists",
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
),
Q("exists", field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD),
Q(
"range",
properties__start_datetime={"lte": datetime_search["lte"]},
Expand Down Expand Up @@ -612,7 +645,7 @@ def apply_bbox_filter(search: Search, bbox: List):
Q(
{
"geo_shape": {
"geometry": {
DatabaseLogic.GEOMETRY_FIELD: {
"shape": {
"type": "polygon",
"coordinates": bbox2polygon(*bbox),
Expand Down