diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/CQLFields.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/CQLFields.java index 4b9df62d..fe7a8316 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/CQLFields.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/CQLFields.java @@ -356,6 +356,17 @@ private static String normalizeDatasetGroupTerm(String value) { return value.toLowerCase(Locale.ROOT).trim(); } + // AAD's indexed group name differs from the acronym users type, so map it here. + // Sorting only: the dataset_group CQL filter stays literal. + private static final Map GROUP_ALIASES = Map.of( + "aad", "australian_antarctic_division"); + + /** A group term plus the alias it stands for, e.g. "aad" -> ["aad", "australian_antarctic_division"]. */ + private static Stream withGroupAliases(String value) { + String alias = GROUP_ALIASES.get(value); + return alias == null ? Stream.of(value) : Stream.of(value, alias); + } + // used by the dataset_group CQL filter only without boost private static Query datasetGroupTermsQuery(List values) { List terms = values.stream() @@ -373,7 +384,8 @@ private static Query datasetGroupTermsQuery(List values) { /** * Expands a free-text term into dataset-group candidate values. For example, "csiro temperature" => ["csiro temperature", "csiro", "temperature"]. * Unquoted input includes both the complete normalized input and its individual words. Double-quoted free-text input is treated as one exact value. - * Dataset-group CQL filters continue to use getPropertyEqualToQuery(). + * Each candidate also carries its GROUP_ALIASES expansion, e.g. "aad" => ["aad", "australian_antarctic_division"]. Aliases apply regardless of quoting, and + * to the priority sort only; dataset-group CQL filters continue to use getPropertyEqualToQuery() and stay literal. */ public static List getDatasetGroupCandidates( String literal, @@ -390,6 +402,7 @@ public static List getDatasetGroupCandidates( return candidates.stream() .filter(value -> !value.isBlank()) + .flatMap(CQLFields::withGroupAliases) .distinct() .toList(); } diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/CQLToElasticFilterFactoryTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/CQLToElasticFilterFactoryTest.java index 29738d70..3f37f117 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/CQLToElasticFilterFactoryTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/CQLToElasticFilterFactoryTest.java @@ -4,6 +4,7 @@ import au.org.aodn.ogcapi.server.core.model.enumeration.CQLElasticSetting; import au.org.aodn.ogcapi.server.core.model.enumeration.CQLFields; import au.org.aodn.ogcapi.server.core.model.enumeration.StacSummeries; +import co.elastic.clients.elasticsearch._types.FieldValue; import co.elastic.clients.elasticsearch._types.query_dsl.ChildScoreMode; import co.elastic.clients.elasticsearch._types.query_dsl.Query; import org.geotools.filter.text.commons.CompilerUtil; diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java index f5a262b7..caf8a4e1 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java @@ -62,6 +62,26 @@ public void searchByParametersWithoutDoubleQuote() throws Exception { "dataset_group priority sort should be the first sort key"); } + // AAD is indexed under a group name that does not look like the acronym users type + @Test + public void datasetGroupPrioritySortExpandsTheAadAcronym() throws Exception { + CapturingElasticSearch capturingSearch = new CapturingElasticSearch(mockClient); + + capturingSearch.searchByParameters( + List.of("aad"), + null, + null, + "-score,-rank", + CQLCrsType.EPSG4326); + + SortOptions prioritySort = capturingSearch.arguments.sortOptions().get(0); + assertTrue(prioritySort.isScript(), "dataset_group priority sort should be the first sort key"); + assertEquals( + List.of("aad", "australian_antarctic_division"), + prioritySort.script().script().params().get("groups").to(List.class), + "aad must also boost records grouped as australian_antarctic_division"); + } + // The portal SEO pipeline requests these in bulk to build Dataset JSON-LD @Test public void seoPropertiesMapToStacFields() throws Exception {