Skip to content

Commit 8c1cae5

Browse files
committed
fields test
1 parent 7ab3887 commit 8c1cae5

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

stac_fastapi/mongo/stac_fastapi/mongo/database_logic.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import base64
33
import logging
44
import os
5+
import re
56
from typing import Any, Dict, Iterable, List, Optional, Protocol, Tuple, Type, Union
67

78
import attr
@@ -229,14 +230,12 @@ async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
229230
@staticmethod
230231
def make_search():
231232
"""Database logic to create a Search instance."""
232-
# return Search().sort(*DEFAULT_SORT)
233-
print("make_search hello")
234233
return MongoSearchAdapter()
235234

236235
@staticmethod
237236
def apply_ids_filter(search: MongoSearchAdapter, item_ids: List[str]):
238237
"""Database logic to search a list of STAC item ids."""
239-
search.add_filter({"_id": {"$in": item_ids}})
238+
search.add_filter({"id": {"$in": item_ids}})
240239
return search
241240

242241
@staticmethod
@@ -405,7 +404,19 @@ def translate_cql2_to_mongo(cql2_filter: Dict[str, Any]) -> Dict[str, Any]:
405404
return {"geometry": {"$geoIntersects": {"$geometry": geometry}}}
406405

407406
elif cql2_filter["op"] == "between":
408-
property_path = "properties." + cql2_filter["args"][0]["property"]
407+
property_name = cql2_filter["args"][0]["property"]
408+
409+
# Use the special mapping directly if available, or construct the path appropriately
410+
if property_name in filter.queryables_mapping:
411+
property_path = filter.queryables_mapping[property_name]
412+
elif property_name not in [
413+
"id",
414+
"collection",
415+
] and not property_name.startswith("properties."):
416+
property_path = f"properties.{property_name}"
417+
else:
418+
property_path = property_name
419+
409420
lower_bound = cql2_filter["args"][1]
410421
upper_bound = cql2_filter["args"][2]
411422
return {property_path: {"$gte": lower_bound, "$lte": upper_bound}}
@@ -442,9 +453,22 @@ def translate_cql2_to_mongo(cql2_filter: Dict[str, Any]) -> Dict[str, Any]:
442453
)
443454

444455
if mongo_op == "$regex":
445-
return {
446-
property_path: {mongo_op: value.replace("%", ".*"), "$options": "i"}
447-
}
456+
# Replace SQL LIKE wildcards with regex equivalents, handling escaped characters
457+
regex_pattern = re.sub(
458+
r"(?<!\\)%", ".*", value
459+
) # Replace '%' with '.*', ignoring escaped '\%'
460+
regex_pattern = re.sub(
461+
r"(?<!\\)_", ".", regex_pattern
462+
) # Replace '_' with '.', ignoring escaped '\_'
463+
464+
# Handle escaped wildcards by reverting them to their literal form
465+
regex_pattern = regex_pattern.replace("\\%", "%").replace("\\_", "_")
466+
467+
# Ensure backslashes are properly escaped for MongoDB regex
468+
regex_pattern = regex_pattern.replace("\\", "\\\\")
469+
470+
return {property_path: {"$regex": regex_pattern, "$options": "i"}}
471+
448472
elif mongo_op == "$in":
449473
if not isinstance(value, list):
450474
raise ValueError(f"Arg {value} is not a list")

0 commit comments

Comments
 (0)