From 74c1d8419c2ea564bc5824d720d3ef941a4d7479 Mon Sep 17 00:00:00 2001 From: HDJ Date: Tue, 4 Jun 2024 14:39:17 +0200 Subject: [PATCH] Stabilize facet ordering according to order in query string Closes #57 --- pom.xml | 2 +- .../huc/broccoli/core/ElasticQueryBuilder.kt | 22 ++++++++++++------- .../resources/projects/ProjectsResource.kt | 19 ++++++++++------ 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 7744ac3..008f396 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ nl.knaw.huc broccoli - 0.34.1 + 0.35.1 jar diff --git a/src/main/kotlin/nl/knaw/huc/broccoli/core/ElasticQueryBuilder.kt b/src/main/kotlin/nl/knaw/huc/broccoli/core/ElasticQueryBuilder.kt index 5f7086e..d55af4b 100644 --- a/src/main/kotlin/nl/knaw/huc/broccoli/core/ElasticQueryBuilder.kt +++ b/src/main/kotlin/nl/knaw/huc/broccoli/core/ElasticQueryBuilder.kt @@ -60,16 +60,16 @@ class ElasticQueryBuilder(private val index: IndexConfiguration) { aggregations = (query.aggregations ?: index.fields.map { it.name }) .map { parseAggregationParameters(it) } .also { logger.atDebug().addArgument(it).log("parsed aggregation params: {}") } - .mapNotNull { args -> - when (index.fields.find { it.name == args.fieldName }?.type) { + .mapNotNull { params -> + when (index.fields.find { it.name == params.fieldName }?.type) { "keyword", "short", "byte" -> TermAggregation( - name = args.fieldName, - numResults = args.numResults, - sortOrder = args.sortOrder + name = params.fieldName, + numResults = params.numResults, + sortOrder = params.sortOrder ) - "date" -> DateAggregation(args.fieldName) + "date" -> DateAggregation(params.fieldName) else -> null } } @@ -100,8 +100,14 @@ class ElasticQueryBuilder(private val index: IndexConfiguration) { } ) ), - aggregations = Aggregations(listOf(TermAggregation(curTerm.key))) - )) + aggregations = Aggregations(listOf( + // use aggregation sort order / count, if specified + query.aggregations?.find { it.startsWith(curTerm.key + ':') }?.let { + parseAggregationParameters(it).let { params -> + TermAggregation(params.fieldName, params.numResults, params.sortOrder) + } + } ?: TermAggregation(curTerm.key)) + ))) } }.toList() diff --git a/src/main/kotlin/nl/knaw/huc/broccoli/resources/projects/ProjectsResource.kt b/src/main/kotlin/nl/knaw/huc/broccoli/resources/projects/ProjectsResource.kt index 68b14dd..7507f56 100644 --- a/src/main/kotlin/nl/knaw/huc/broccoli/resources/projects/ProjectsResource.kt +++ b/src/main/kotlin/nl/knaw/huc/broccoli/resources/projects/ProjectsResource.kt @@ -120,11 +120,12 @@ class ProjectsResource( .also { logger.trace("base json: {}", it) } val result = mutableMapOf() + val aggs = mutableMapOf() jsonParser.parse(baseJson).let { context -> context.read>("$.hits.total") ?.let { result["total"] = it } - extractAggregations(context)?.let { result["aggs"] = it } + extractAggregations(context)?.let { aggs.putAll(it) } context.read>>("$.hits.hits[*]") ?.map { buildHitResult(index, it) } @@ -140,12 +141,16 @@ class ProjectsResource( val auxJson = auxResult.readEntityAsJsonString() .also { logger.trace("aux json[{}]: {}", auxIndex, it) } jsonParser.parse(auxJson).let { context -> - extractAggregations(context)?.let { aggs -> - logger.debug("AUX[{}] extracted aggs: {}", auxIndex, aggs) - @Suppress("UNCHECKED_CAST") - (result["aggs"] as MutableMap).apply { - aggs.forEach { (key, value) -> put(key, value) } - } + extractAggregations(context)?.let { aggs.putAll(it) } + } + } + + // if aggregations are requested, order them according to query string + (queryString.aggregations ?: index.fields.map { it.name }).let { orderedAggregationNames -> + result["aggs"] = LinkedHashMap().apply { + orderedAggregationNames.forEach { unparsedName -> + val parsedName = unparsedName.substringBefore(":") + aggs[parsedName]?.let { put(parsedName, it) } } } }