Repository: stac-utils/stac-fastapi-elasticsearch-opensearch (language: python)

Issue:
GET /search filter-lang doesn't default to cql2-text
**Describe the bug**
The GET /search filter-lang parameter doesn't default to cql2-text, like it is defined in the specification of the filter extension. Instead, cql2-json is used as the default when no value is supplied.
https://github.com/stac-api-extensions/filter?tab=readme-ov-file#get-query-parameters-and-post-json-fields

https://github.com/stac-utils/stac-fastapi-elasticsearch/blob/main/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py#L383-L388


**To Reproduce**
Steps to reproduce the behavior:
1. Perform a GET /search request with the filter parameter (eg. filter=cloud_cover < 10).
2. The filter cannot be parsed and an error is returned.


**Expected behavior**
The default filter-lang in a GET search is cql2-text and queries can be parsed successfully.

GET /search filter-lang doesn't default to cql2-text
**Describe the bug**
The GET /search filter-lang parameter doesn't default to cql2-text, like it is defined in the specification of the filter extension. Instead, cql2-json is used as the default when no value is supplied.
https://github.com/stac-api-extensions/filter?tab=readme-ov-file#get-query-parameters-and-post-json-fields

https://github.com/stac-utils/stac-fastapi-elasticsearch/blob/main/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py#L383-L388


**To Reproduce**
Steps to reproduce the behavior:
1. Perform a GET /search request with the filter parameter (eg. filter=cloud_cover < 10).
2. The filter cannot be parsed and an error is returned.


**Expected behavior**
The default filter-lang in a GET search is cql2-text and queries can be parsed successfully.



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 03160fe9..4c3f4a61 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 - Exclude unset fields in search response [#166](https://github.com/stac-utils/stac-fastapi-elasticsearch/issues/166)
 - Upgrade stac-fastapi to v2.4.9 [#172](https://github.com/stac-utils/stac-fastapi-elasticsearch/pull/172)
+- Set correct default filter-lang for GET /search requests [#179](https://github.com/stac-utils/stac-fastapi-elasticsearch/issues/179)
 
 ## [v1.0.0]
 
diff --git a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py
index 4fb9f174..12cc6b2c 100644
--- a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py
+++ b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py
@@ -380,12 +380,12 @@ async def get_search(
             base_args["sortby"] = sort_param
 
         if filter:
-            if filter_lang == "cql2-text":
+            if filter_lang == "cql2-json":
                 base_args["filter-lang"] = "cql2-json"
-                base_args["filter"] = orjson.loads(to_cql2(parse_cql2_text(filter)))
+                base_args["filter"] = orjson.loads(unquote_plus(filter))
             else:
                 base_args["filter-lang"] = "cql2-json"
-                base_args["filter"] = orjson.loads(unquote_plus(filter))
+                base_args["filter"] = orjson.loads(to_cql2(parse_cql2_text(filter)))
 
         if fields:
             includes = set()


Test patch:
diff --git a/stac_fastapi/elasticsearch/tests/extensions/test_filter.py b/stac_fastapi/elasticsearch/tests/extensions/test_filter.py
index c5e521bc..72cea59f 100644
--- a/stac_fastapi/elasticsearch/tests/extensions/test_filter.py
+++ b/stac_fastapi/elasticsearch/tests/extensions/test_filter.py
@@ -101,6 +101,17 @@ async def test_search_filter_ext_and_get(app_client, ctx):
     assert len(resp.json()["features"]) == 1
 
 
+@pytest.mark.asyncio
+async def test_search_filter_ext_and_get_id(app_client, ctx):
+    collection = ctx.item["collection"]
+    id = ctx.item["id"]
+    filter = f"id='{id}' AND collection='{collection}'"
+    resp = await app_client.get(f"/search?&filter={filter}")
+
+    assert resp.status_code == 200
+    assert len(resp.json()["features"]) == 1
+
+
 @pytest.mark.asyncio
 async def test_search_filter_ext_and_get_cql2text_id(app_client, ctx):
     collection = ctx.item["collection"]
@@ -162,21 +173,21 @@ async def test_search_filter_ext_and_post(app_client, ctx):
 @pytest.mark.asyncio
 async def test_search_filter_extension_floats_get(app_client, ctx):
     resp = await app_client.get(
-        """/search?filter={"op":"and","args":[{"op":"=","args":[{"property":"id"},"test-item"]},{"op":">","args":[{"property":"properties.view:sun_elevation"},"-37.30891534"]},{"op":"<","args":[{"property":"properties.view:sun_elevation"},"-37.30691534"]}]}"""
+        """/search?filter-lang=cql2-json&filter={"op":"and","args":[{"op":"=","args":[{"property":"id"},"test-item"]},{"op":">","args":[{"property":"properties.view:sun_elevation"},"-37.30891534"]},{"op":"<","args":[{"property":"properties.view:sun_elevation"},"-37.30691534"]}]}"""
     )
 
     assert resp.status_code == 200
     assert len(resp.json()["features"]) == 1
 
     resp = await app_client.get(
-        """/search?filter={"op":"and","args":[{"op":"=","args":[{"property":"id"},"test-item-7"]},{"op":">","args":[{"property":"properties.view:sun_elevation"},"-37.30891534"]},{"op":"<","args":[{"property":"properties.view:sun_elevation"},"-37.30691534"]}]}"""
+        """/search?filter-lang=cql2-json&filter={"op":"and","args":[{"op":"=","args":[{"property":"id"},"test-item-7"]},{"op":">","args":[{"property":"properties.view:sun_elevation"},"-37.30891534"]},{"op":"<","args":[{"property":"properties.view:sun_elevation"},"-37.30691534"]}]}"""
     )
 
     assert resp.status_code == 200
     assert len(resp.json()["features"]) == 0
 
     resp = await app_client.get(
-        """/search?filter={"op":"and","args":[{"op":"=","args":[{"property":"id"},"test-item"]},{"op":">","args":[{"property":"properties.view:sun_elevation"},"-37.30591534"]},{"op":"<","args":[{"property":"properties.view:sun_elevation"},"-37.30491534"]}]}"""
+        """/search?filter-lang=cql2-json&filter={"op":"and","args":[{"op":"=","args":[{"property":"id"},"test-item"]},{"op":">","args":[{"property":"properties.view:sun_elevation"},"-37.30591534"]},{"op":"<","args":[{"property":"properties.view:sun_elevation"},"-37.30491534"]}]}"""
     )
 
     assert resp.status_code == 200