From ed0a04f4b1ecae69358a53e814557ba3c69e8e9d Mon Sep 17 00:00:00 2001 From: Jilles van Gurp Date: Fri, 31 Jan 2025 12:21:28 +0100 Subject: [PATCH] add helper functions for geotile_grid and geo_centroid --- .../manual/search/aggregations.kt | 17 +++-- .../jillesvangurp/ktsearch/SearchResponse.kt | 71 ++++++++++++++----- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/docs/src/test/kotlin/documentation/manual/search/aggregations.kt b/docs/src/test/kotlin/documentation/manual/search/aggregations.kt index 27c5c80e..505ff291 100644 --- a/docs/src/test/kotlin/documentation/manual/search/aggregations.kt +++ b/docs/src/test/kotlin/documentation/manual/search/aggregations.kt @@ -251,17 +251,24 @@ val aggregationsMd = sourceGitRepository.md { """.trimIndent() example { - client.search(indexName) { + val response = client.search(indexName) { resultSize = 0 agg("grid", GeoTileGridAgg(TestGeoDoc::point.name,13)) { agg("centroid", GeoCentroidAgg(TestGeoDoc::point.name)) } } - }.let { - it.result.getOrNull()?.let { - mdCodeBlock(DEFAULT_PRETTY_JSON.encodeToString(it), type="json",wrap = true) + + println( + DEFAULT_PRETTY_JSON.encodeToString(response) + ) + val geoTiles = response.aggregations.geoTileGridResult("grid") + geoTiles.parsedBuckets.forEach { bucket -> + bucket.aggregations.geoCentroid("centroid").let { + val key = bucket.parsed.key + println("$key: ${it.location} - ${it.count} ") + } } - } + }.printStdOut() } diff --git a/search-client/src/commonMain/kotlin/com/jillesvangurp/ktsearch/SearchResponse.kt b/search-client/src/commonMain/kotlin/com/jillesvangurp/ktsearch/SearchResponse.kt index 5194ca06..006fa308 100644 --- a/search-client/src/commonMain/kotlin/com/jillesvangurp/ktsearch/SearchResponse.kt +++ b/search-client/src/commonMain/kotlin/com/jillesvangurp/ktsearch/SearchResponse.kt @@ -4,6 +4,8 @@ package com.jillesvangurp.ktsearch import com.jillesvangurp.ktsearch.repository.ModelSerializationStrategy +import com.jillesvangurp.searchdsls.querydsl.GeoTileGridAgg +import com.jillesvangurp.searchdsls.querydsl.Shape import com.jillesvangurp.serializationext.DEFAULT_JSON import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map @@ -131,6 +133,7 @@ inline fun Flow.parseHits( ): Flow = map { it.parseHit() } + fun Flow.parseHits( deserializationStrategy: DeserializationStrategy, json: Json = DEFAULT_JSON @@ -138,7 +141,7 @@ fun Flow.parseHits( it.parseHit(deserializationStrategy, json) } -fun Flow.parseHits(deserializationStrategy: ModelSerializationStrategy): Flow = +fun Flow.parseHits(deserializationStrategy: ModelSerializationStrategy): Flow = mapNotNull { hit -> hit.source?.let { deserializationStrategy.deSerialize(it) } } @@ -381,29 +384,29 @@ data class ExtendedStatsBucketResult( @EncodeDefault val max: Double = 0.0, @EncodeDefault - val avg: Double= 0.0, + val avg: Double = 0.0, @EncodeDefault - val sum: Double= 0.0, + val sum: Double = 0.0, @SerialName("sum_of_squares") @EncodeDefault - val sumOfSquares: Double= 0.0, + val sumOfSquares: Double = 0.0, @EncodeDefault - val variance: Double= 0.0, + val variance: Double = 0.0, @SerialName("variance_population") @EncodeDefault - val variancePopulation: Double= 0.0, + val variancePopulation: Double = 0.0, @SerialName("variance_sampling") @EncodeDefault - val varianceSampling: Double= 0.0, + val varianceSampling: Double = 0.0, @SerialName("std_deviation") @EncodeDefault - val stdDeviation: Double= 0.0, + val stdDeviation: Double = 0.0, @SerialName("std_deviation_population") @EncodeDefault - val stdDeviationPopulation: Double= 0.0, + val stdDeviationPopulation: Double = 0.0, @SerialName("std_deviation_sampling") @EncodeDefault - val stdDeviationSampling: Double= 0.0, + val stdDeviationSampling: Double = 0.0, @SerialName("std_deviation_bounds") @EncodeDefault val stdDeviationBounds: Bounds = Bounds() @@ -411,21 +414,21 @@ data class ExtendedStatsBucketResult( @Serializable data class Bounds( @EncodeDefault - val upper: Double= 0.0, + val upper: Double = 0.0, @EncodeDefault - val lower: Double= 0.0, + val lower: Double = 0.0, @SerialName("upper_population") @EncodeDefault - val upperPopulation: Double= 0.0, + val upperPopulation: Double = 0.0, @SerialName("lower_population") @EncodeDefault - val lowerPopulation: Double= 0.0, + val lowerPopulation: Double = 0.0, @SerialName("upper_sampling") @EncodeDefault - val upperSampling: Double= 0.0, + val upperSampling: Double = 0.0, @SerialName("lower_sampling") @EncodeDefault - val lowerSampling: Double= 0.0, + val lowerSampling: Double = 0.0, ) } @@ -446,6 +449,42 @@ fun Aggregations?.topHitResult(name: String, json: Json = DEFAULT_JSON): TopHits fun Aggregations?.topHitResult(name: Enum<*>, json: Json = DEFAULT_JSON): TopHitsAggregationResult = getAggResult(name.name, json) +@Serializable +data class GeoTileGridBucket( + val key: String, + @SerialName("doc_count") + val docCount: Long, +) + +@Serializable +data class GeoTileGridResult( + override val buckets: List +) : BucketAggregationResult + +val GeoTileGridResult.parsedBuckets get() = buckets.map { Bucket(it, GeoTileGridBucket.serializer()) } + +fun Aggregations?.geoTileGridResult(name: String, json: Json = DEFAULT_JSON): GeoTileGridResult = + getAggResult(name, json) + +fun Aggregations?.geoTileGridResult(name: Enum<*>, json: Json = DEFAULT_JSON): GeoTileGridResult = + getAggResult(name, json) + + +@Serializable +data class GeoCentroidResult( + val location: Point, + val count: Long, + + ) { + val pointCoordinate get() = doubleArrayOf(location.lon, location.lat) + + @Serializable + data class Point(val lat: Double, val lon: Double) +} + +fun Aggregations?.geoCentroid(name: String) = getAggResult(name) +fun Aggregations?.geoCentroid(name: Enum<*>) = getAggResult(name) + @Serializable data class SumAggregationResult( val value: Double,