Skip to content

Commit 72ff9de

Browse files
committed
Merge branch 'main' into sfes-mongo
merge main
2 parents 0b2d160 + ad2dc7e commit 72ff9de

File tree

5 files changed

+73
-41
lines changed

5 files changed

+73
-41
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
### Added
1111

12+
- Added explicit mapping for ID in `ES_COLLECTIONS_MAPPINGS` [#198](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/198)
13+
1214
### Changed
1315

16+
- Removed database logic from core.py all_collections [#196](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/196)
17+
- Changed OpenSearch config ssl_version to SSLv23 [#200](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/200)
18+
1419
### Fixed
1520

1621
## [v2.0.0]

stac_fastapi/core/stac_fastapi/core/core.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,9 @@ async def get_collection(self, collection_id: str, **kwargs) -> Collection:
238238
"""
239239
base_url = str(kwargs["request"].base_url)
240240
collection = await self.database.find_collection(collection_id=collection_id)
241-
return self.collection_serializer.db_to_stac(collection, base_url)
241+
return self.collection_serializer.db_to_stac(
242+
collection=collection, base_url=base_url
243+
)
242244

243245
async def item_collection(
244246
self,

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"numeric_detection": False,
133133
"dynamic_templates": ES_MAPPINGS_DYNAMIC_TEMPLATES,
134134
"properties": {
135+
"id": {"type": "keyword"},
135136
"extent.spatial.bbox": {"type": "long"},
136137
"extent.temporal.interval": {"type": "date"},
137138
"providers": {"type": "object", "enabled": False},
@@ -290,33 +291,43 @@ class DatabaseLogic:
290291
"""CORE LOGIC"""
291292

292293
async def get_all_collections(
293-
self, token: Optional[str], limit: int
294-
) -> Iterable[Dict[str, Any]]:
295-
"""Retrieve a list of all collections from the database.
294+
self, token: Optional[str], limit: int, base_url: str
295+
) -> Tuple[List[Dict[str, Any]], Optional[str]]:
296+
"""Retrieve a list of all collections from Elasticsearch, supporting pagination.
296297
297298
Args:
298-
token (Optional[str]): The token used to return the next set of results.
299-
limit (int): Number of results to return
299+
token (Optional[str]): The pagination token.
300+
limit (int): The number of results to return.
300301
301302
Returns:
302-
collections (Iterable[Dict[str, Any]]): A list of dictionaries containing the source data for each collection.
303-
304-
Notes:
305-
The collections are retrieved from the Elasticsearch database using the `client.search` method,
306-
with the `COLLECTIONS_INDEX` as the target index and `size=limit` to retrieve records.
307-
The result is a generator of dictionaries containing the source data for each collection.
303+
A tuple of (collections, next pagination token if any).
308304
"""
309305
search_after = None
310306
if token:
311-
search_after = urlsafe_b64decode(token.encode()).decode().split(",")
312-
collections = await self.client.search(
307+
search_after = [token]
308+
309+
response = await self.client.search(
313310
index=COLLECTIONS_INDEX,
314-
search_after=search_after,
315-
size=limit,
316-
sort={"id": {"order": "asc"}},
311+
body={
312+
"sort": [{"id": {"order": "asc"}}],
313+
"size": limit,
314+
"search_after": search_after,
315+
},
317316
)
318-
hits = collections["hits"]["hits"]
319-
return hits
317+
318+
hits = response["hits"]["hits"]
319+
collections = [
320+
self.collection_serializer.db_to_stac(
321+
collection=hit["_source"], base_url=base_url
322+
)
323+
for hit in hits
324+
]
325+
326+
next_token = None
327+
if len(hits) == limit:
328+
next_token = hits[-1]["sort"][0]
329+
330+
return collections, next_token
320331

321332
async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
322333
"""Retrieve a single item from the database.

stac_fastapi/opensearch/stac_fastapi/opensearch/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def _es_config() -> Dict[str, Any]:
2727
return config
2828

2929
# Include SSL settings if using https
30-
config["ssl_version"] = ssl.TLSVersion.TLSv1_3 # type: ignore
30+
config["ssl_version"] = ssl.PROTOCOL_SSLv23 # type: ignore
3131
config["verify_certs"] = os.getenv("ES_VERIFY_CERTS", "true").lower() != "false" # type: ignore
3232

3333
# Include CA Certificates if verifying certs

stac_fastapi/opensearch/stac_fastapi/opensearch/database_logic.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
"numeric_detection": False,
135135
"dynamic_templates": ES_MAPPINGS_DYNAMIC_TEMPLATES,
136136
"properties": {
137+
"id": {"type": "keyword"},
137138
"extent.spatial.bbox": {"type": "long"},
138139
"extent.temporal.interval": {"type": "date"},
139140
"providers": {"type": "object", "enabled": False},
@@ -311,36 +312,49 @@ class DatabaseLogic:
311312
"""CORE LOGIC"""
312313

313314
async def get_all_collections(
314-
self,
315-
token: Optional[str],
316-
limit: int,
317-
) -> Iterable[Dict[str, Any]]:
318-
"""Retrieve a list of all collections from the database.
315+
self, token: Optional[str], limit: int, base_url: str
316+
) -> Tuple[List[Dict[str, Any]], Optional[str]]:
317+
"""
318+
Retrieve a list of all collections from Opensearch, supporting pagination.
319319
320320
Args:
321-
token (Optional[str]): The token used to return the next set of results.
322-
limit (int): Number of results to return
321+
token (Optional[str]): The pagination token.
322+
limit (int): The number of results to return.
323323
324324
Returns:
325-
collections (Iterable[Dict[str, Any]]): A list of dictionaries containing the source data for each collection.
326-
327-
Notes:
328-
The collections are retrieved from the Elasticsearch database using the `client.search` method,
329-
with the `COLLECTIONS_INDEX` as the target index and `size=limit` to retrieve records.
330-
The result is a generator of dictionaries containing the source data for each collection.
325+
A tuple of (collections, next pagination token if any).
331326
"""
332-
search_body: Dict[str, Any] = {}
327+
search_body = {
328+
"sort": [{"id": {"order": "asc"}}],
329+
"size": limit,
330+
}
331+
332+
# Only add search_after to the query if token is not None and not empty
333333
if token:
334-
search_after = urlsafe_b64decode(token.encode()).decode().split(",")
334+
search_after = [token]
335335
search_body["search_after"] = search_after
336336

337-
search_body["sort"] = {"id": {"order": "asc"}}
338-
339-
collections = await self.client.search(
340-
index=COLLECTIONS_INDEX, body=search_body, size=limit
337+
response = await self.client.search(
338+
index="collections",
339+
body=search_body,
341340
)
342-
hits = collections["hits"]["hits"]
343-
return hits
341+
342+
hits = response["hits"]["hits"]
343+
collections = [
344+
self.collection_serializer.db_to_stac(
345+
collection=hit["_source"], base_url=base_url
346+
)
347+
for hit in hits
348+
]
349+
350+
next_token = None
351+
if len(hits) == limit:
352+
# Ensure we have a valid sort value for next_token
353+
next_token_values = hits[-1].get("sort")
354+
if next_token_values:
355+
next_token = next_token_values[0]
356+
357+
return collections, next_token
344358

345359
async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
346360
"""Retrieve a single item from the database.

0 commit comments

Comments
 (0)