From d34032ceda94232c09cfbfb8eebc5ceda19614c3 Mon Sep 17 00:00:00 2001 From: "a.usenko" Date: Fri, 21 Jul 2023 13:16:43 +0300 Subject: [PATCH 1/6] Add explanation to hits --- .../kotlin/dev/evo/elasticmagic/Result.kt | 7 ++++ .../compile/SearchQueryCompiler.kt | 33 ++++++++++++++----- .../elasticmagic/qf/AttrSimpleFiltersTest.kt | 18 +++++++++- .../elasticmagic/compile/BaseCompilerTest.kt | 4 +-- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt index 181ce4421d..e084d9abd4 100644 --- a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt +++ b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt @@ -41,6 +41,12 @@ data class MultiSearchQueryResult( } } +data class Explanation( + val value: Float, + val description: String, + val details: List = emptyList(), +) + data class SearchHit( val index: String, val type: String, @@ -53,6 +59,7 @@ data class SearchHit( val sort: List? = null, val source: S? = null, val fields: Fields = Fields(emptyMap()), + val explanation: Explanation? = null, ) : ActionMeta { class Fields(private val fields: Map>) { /** diff --git a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt index d8334eae50..894c62e65a 100644 --- a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt +++ b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt @@ -1,9 +1,13 @@ package dev.evo.elasticmagic.compile import dev.evo.elasticmagic.AsyncResult +import dev.evo.elasticmagic.BulkError +import dev.evo.elasticmagic.BulkScrollFailure import dev.evo.elasticmagic.BulkScrollRetries import dev.evo.elasticmagic.CountResult +import dev.evo.elasticmagic.DeleteByQueryPartialResult import dev.evo.elasticmagic.DeleteByQueryResult +import dev.evo.elasticmagic.Explanation import dev.evo.elasticmagic.MultiSearchQueryResult import dev.evo.elasticmagic.Params import dev.evo.elasticmagic.PreparedSearchQuery @@ -11,6 +15,7 @@ import dev.evo.elasticmagic.SearchHit import dev.evo.elasticmagic.SearchQuery import dev.evo.elasticmagic.SearchQueryResult import dev.evo.elasticmagic.ToValue +import dev.evo.elasticmagic.UpdateByQueryPartialResult import dev.evo.elasticmagic.UpdateByQueryResult import dev.evo.elasticmagic.WithIndex import dev.evo.elasticmagic.doc.BaseDocSource @@ -33,16 +38,12 @@ import dev.evo.elasticmagic.transport.BulkRequest import dev.evo.elasticmagic.transport.ApiRequest import dev.evo.elasticmagic.transport.Method import dev.evo.elasticmagic.transport.Parameters -import dev.evo.elasticmagic.BulkError -import dev.evo.elasticmagic.BulkScrollFailure -import dev.evo.elasticmagic.UpdateByQueryPartialResult -import dev.evo.elasticmagic.DeleteByQueryPartialResult abstract class BaseSearchQueryCompiler( features: ElasticsearchFeatures, ) : BaseCompiler(features) { - interface Visitable { + interface Visitable { fun accept(ctx: T, compiler: BaseSearchQueryCompiler) } @@ -218,7 +219,7 @@ open class SearchQueryCompiler( ) } - fun processResult( + fun processResult( ctx: Deserializer.ObjectCtx, preparedSearchQuery: SearchQuery.Search, ): SearchQueryResult { @@ -231,7 +232,7 @@ open class SearchQueryCompiler( } val rawHits = rawHitsData.arrayOrNull("hits") - val hits = buildList> { + val hits = buildList { rawHits?.forEachObj { rawHit -> add(processSearchHit(rawHit, preparedSearchQuery)) } @@ -259,7 +260,7 @@ open class SearchQueryCompiler( ) } - private fun processSearchHit( + private fun processSearchHit( rawHit: Deserializer.ObjectCtx, preparedSearchQuery: SearchQuery.Search, ): SearchHit { @@ -295,8 +296,24 @@ open class SearchQueryCompiler( sort = sort.ifEmpty { null }, source = source, fields = fields, + explanation = if (preparedSearchQuery.params.containsKey("explain")) parseExplanation(rawHit.obj("_explanation")) else null, ) } + + private fun parseExplanation(rawHit: Deserializer.ObjectCtx): Explanation { + val description = rawHit.string("description") + val value = rawHit.float("value") + val explanation = + rawHit.arrayOrNull("details")?.let { + buildList { + it.forEachObj { rawExplanation -> + add(parseExplanation(rawExplanation)) + } + } + } + + return Explanation(value, description, explanation ?: emptyList()) + } } class CountQueryCompiler( diff --git a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt index b292099664..5b47baa4e1 100644 --- a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt +++ b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt @@ -1,10 +1,21 @@ package dev.evo.elasticmagic.qf import dev.evo.elasticmagic.ElasticsearchTestBase +import dev.evo.elasticmagic.Params import dev.evo.elasticmagic.SearchQuery +import dev.evo.elasticmagic.doc.BoundField +import dev.evo.elasticmagic.doc.RootFieldSet +import dev.evo.elasticmagic.types.TextType import io.kotest.matchers.shouldBe import kotlin.test.Test +class StringField(name: String) : BoundField( + name, + TextType, + Params(), + RootFieldSet +) + class AttrSimpleFiltersTest : ElasticsearchTestBase() { override val indexName = "attr-simple-filter" @@ -18,7 +29,12 @@ class AttrSimpleFiltersTest : ElasticsearchTestBase() { fun attrSimpleFilterTest() = runTestWithSerdes { withFixtures(ItemDoc, FIXTURES) { val searchQuery = SearchQuery() - searchQuery.execute(index).totalHits shouldBe 8 + val result = searchQuery.execute(index) + result.totalHits shouldBe 8 + result.hits.mapNotNull { + it.explanation + }.size shouldBe 0 + ItemQueryFilters.apply( searchQuery, diff --git a/test-utils/src/commonMain/kotlin/dev/evo/elasticmagic/compile/BaseCompilerTest.kt b/test-utils/src/commonMain/kotlin/dev/evo/elasticmagic/compile/BaseCompilerTest.kt index fe9d85c12b..be5f4de305 100644 --- a/test-utils/src/commonMain/kotlin/dev/evo/elasticmagic/compile/BaseCompilerTest.kt +++ b/test-utils/src/commonMain/kotlin/dev/evo/elasticmagic/compile/BaseCompilerTest.kt @@ -4,8 +4,6 @@ import dev.evo.elasticmagic.BaseTest import dev.evo.elasticmagic.Params import dev.evo.elasticmagic.SearchQuery import dev.evo.elasticmagic.withIndex -import dev.evo.elasticmagic.doc.BaseDocSource - import io.kotest.matchers.types.shouldBeInstanceOf @Suppress("UnnecessaryAbstractClass") @@ -35,7 +33,7 @@ abstract class BaseCompilerTest( ) protected fun SearchQueryCompiler.compile(query: SearchQuery<*>): CompiledSearchQuery { - val compiled = this@compile.compile(serde, query.prepareSearch().withIndex("test")) + val compiled = this@compile.compile(serde, query.prepareSearch().withIndex("test")) return CompiledSearchQuery( params = compiled.parameters, body = compiled.body.shouldBeInstanceOf().toMap(), From 5685d128c0f48762b10a7f5f01db4250f0f5ce83 Mon Sep 17 00:00:00 2001 From: "a.usenko" Date: Fri, 21 Jul 2023 18:23:11 +0300 Subject: [PATCH 2/6] Add test --- .../dev/evo/elasticmagic/ExplanationTest.kt | 60 +++++++++++++++++++ .../elasticmagic/qf/AttrSimpleFiltersTest.kt | 15 ----- 2 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt diff --git a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt new file mode 100644 index 0000000000..3bf1b62963 --- /dev/null +++ b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt @@ -0,0 +1,60 @@ +package dev.evo.elasticmagic + +import dev.evo.elasticmagic.doc.BoundField +import dev.evo.elasticmagic.doc.RootFieldSet +import dev.evo.elasticmagic.qf.FIXTURES +import dev.evo.elasticmagic.qf.ItemDoc +import dev.evo.elasticmagic.query.match +import dev.evo.elasticmagic.types.TextType +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import kotlin.test.Test + +class ExplanationTest : ElasticsearchTestBase() { + override val indexName = "explanation-test" + + class StringField(name: String) : BoundField( + name, + TextType, + Params(), + RootFieldSet + ) + + @Test + fun withoutExplanation() = runTestWithSerdes { + withFixtures(ItemDoc, FIXTURES) { + val searchQuery = SearchQuery() + val result = searchQuery.execute(index) + result.totalHits shouldBe 8 + result.hits.mapNotNull { it.explanation } shouldBe emptyList() + } + } + + @Test + fun withExplanationButEmptySearchQuery() = runTestWithSerdes { + withFixtures(ItemDoc, FIXTURES) { + val searchQuery = SearchQuery() + val result = searchQuery.execute(index, Params("explain" to true)) + result.totalHits shouldBe 8 + val explanations = result.hits.mapNotNull { it.explanation } + + explanations.size shouldBe 800 + explanations.map { it.details shouldBe emptyList() } + + } + } + + @Test + fun withExplanation() = runTestWithSerdes { + withFixtures(ItemDoc, FIXTURES) { + val searchQuery = SearchQuery(StringField("model").match("Galaxy Note 10")) + val result = searchQuery.execute(index, Params("explain" to true)) + result.totalHits shouldBe 5 + val explanations = result.hits.mapNotNull { it.explanation } + + explanations.size shouldBe 5 + explanations.map { it.details.size shouldNotBe 0 } + + } + } +} diff --git a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt index 5b47baa4e1..64914c6992 100644 --- a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt +++ b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/qf/AttrSimpleFiltersTest.kt @@ -1,21 +1,10 @@ package dev.evo.elasticmagic.qf import dev.evo.elasticmagic.ElasticsearchTestBase -import dev.evo.elasticmagic.Params import dev.evo.elasticmagic.SearchQuery -import dev.evo.elasticmagic.doc.BoundField -import dev.evo.elasticmagic.doc.RootFieldSet -import dev.evo.elasticmagic.types.TextType import io.kotest.matchers.shouldBe import kotlin.test.Test -class StringField(name: String) : BoundField( - name, - TextType, - Params(), - RootFieldSet -) - class AttrSimpleFiltersTest : ElasticsearchTestBase() { override val indexName = "attr-simple-filter" @@ -31,10 +20,6 @@ class AttrSimpleFiltersTest : ElasticsearchTestBase() { val searchQuery = SearchQuery() val result = searchQuery.execute(index) result.totalHits shouldBe 8 - result.hits.mapNotNull { - it.explanation - }.size shouldBe 0 - ItemQueryFilters.apply( searchQuery, From 66747e1d4b5d2a612d0a632dbc44d545741a6ec7 Mon Sep 17 00:00:00 2001 From: "a.usenko" Date: Mon, 24 Jul 2023 12:07:01 +0300 Subject: [PATCH 3/6] fix test --- .../commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt index 3bf1b62963..e394e80b58 100644 --- a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt +++ b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt @@ -38,7 +38,7 @@ class ExplanationTest : ElasticsearchTestBase() { result.totalHits shouldBe 8 val explanations = result.hits.mapNotNull { it.explanation } - explanations.size shouldBe 800 + explanations.size shouldBe 8 explanations.map { it.details shouldBe emptyList() } } From c4d4bcd1c10aa575865b0d91d33ed539021eca23 Mon Sep 17 00:00:00 2001 From: "a.usenko" Date: Mon, 24 Jul 2023 12:07:52 +0300 Subject: [PATCH 4/6] fix type declaration --- .../src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt index e084d9abd4..e37b21f888 100644 --- a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt +++ b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/Result.kt @@ -93,7 +93,7 @@ data class SearchHit( * @throws dev.evo.elasticmagic.types.ValueDeserializationException if the field value * cannot be deserialized. */ - operator fun get(field: BoundField): List? { + operator fun get(field: BoundField): List { return this[field.getQualifiedFieldName()] .map(field.getFieldType()::deserialize) } From b6756fa872e7958525e2da52711dc8733cecb4a1 Mon Sep 17 00:00:00 2001 From: "a.usenko" Date: Mon, 24 Jul 2023 12:31:57 +0300 Subject: [PATCH 5/6] Fix detekt and dump api --- elasticmagic/api/elasticmagic.api | 26 ++++++++++++++++--- .../compile/SearchQueryCompiler.kt | 7 +++-- .../dev/evo/elasticmagic/SearchQueryTests.kt | 17 +++++------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/elasticmagic/api/elasticmagic.api b/elasticmagic/api/elasticmagic.api index 2b0d3cc58b..5f8f7dab92 100644 --- a/elasticmagic/api/elasticmagic.api +++ b/elasticmagic/api/elasticmagic.api @@ -386,6 +386,22 @@ public final class dev/evo/elasticmagic/ElasticsearchIndex { public final fun updateByQueryAsync (Ldev/evo/elasticmagic/SearchQuery$Update;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } +public final class dev/evo/elasticmagic/Explanation { + public fun (FLjava/lang/String;Ljava/util/List;)V + public synthetic fun (FLjava/lang/String;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()F + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/util/List; + public final fun copy (FLjava/lang/String;Ljava/util/List;)Ldev/evo/elasticmagic/Explanation; + public static synthetic fun copy$default (Ldev/evo/elasticmagic/Explanation;FLjava/lang/String;Ljava/util/List;ILjava/lang/Object;)Ldev/evo/elasticmagic/Explanation; + public fun equals (Ljava/lang/Object;)Z + public final fun getDescription ()Ljava/lang/String; + public final fun getDetails ()Ljava/util/List; + public final fun getValue ()F + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public final class dev/evo/elasticmagic/MultiSearchQueryResult { public fun (Ljava/lang/Long;Ljava/util/List;)V public final fun component1 ()Ljava/lang/Long; @@ -443,11 +459,12 @@ public final class dev/evo/elasticmagic/Refresh : java/lang/Enum, dev/evo/elasti } public final class dev/evo/elasticmagic/SearchHit : dev/evo/elasticmagic/bulk/ActionMeta { - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;Ldev/evo/elasticmagic/Explanation;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;Ldev/evo/elasticmagic/Explanation;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; public final fun component10 ()Ldev/evo/elasticmagic/doc/BaseDocSource; public final fun component11 ()Ldev/evo/elasticmagic/SearchHit$Fields; + public final fun component12 ()Ldev/evo/elasticmagic/Explanation; public final fun component2 ()Ljava/lang/String; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; @@ -456,9 +473,10 @@ public final class dev/evo/elasticmagic/SearchHit : dev/evo/elasticmagic/bulk/Ac public final fun component7 ()Ljava/lang/Long; public final fun component8 ()Ljava/lang/Float; public final fun component9 ()Ljava/util/List; - public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;)Ldev/evo/elasticmagic/SearchHit; - public static synthetic fun copy$default (Ldev/evo/elasticmagic/SearchHit;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;ILjava/lang/Object;)Ldev/evo/elasticmagic/SearchHit; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;Ldev/evo/elasticmagic/Explanation;)Ldev/evo/elasticmagic/SearchHit; + public static synthetic fun copy$default (Ldev/evo/elasticmagic/SearchHit;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Float;Ljava/util/List;Ldev/evo/elasticmagic/doc/BaseDocSource;Ldev/evo/elasticmagic/SearchHit$Fields;Ldev/evo/elasticmagic/Explanation;ILjava/lang/Object;)Ldev/evo/elasticmagic/SearchHit; public fun equals (Ljava/lang/Object;)Z + public final fun getExplanation ()Ldev/evo/elasticmagic/Explanation; public final fun getFields ()Ldev/evo/elasticmagic/SearchHit$Fields; public fun getId ()Ljava/lang/String; public final fun getIndex ()Ljava/lang/String; diff --git a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt index 894c62e65a..86f1f4c376 100644 --- a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt +++ b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt @@ -34,8 +34,8 @@ import dev.evo.elasticmagic.serde.forEachObj import dev.evo.elasticmagic.serde.toList import dev.evo.elasticmagic.serde.toMap import dev.evo.elasticmagic.toRequestParameters -import dev.evo.elasticmagic.transport.BulkRequest import dev.evo.elasticmagic.transport.ApiRequest +import dev.evo.elasticmagic.transport.BulkRequest import dev.evo.elasticmagic.transport.Method import dev.evo.elasticmagic.transport.Parameters @@ -296,7 +296,10 @@ open class SearchQueryCompiler( sort = sort.ifEmpty { null }, source = source, fields = fields, - explanation = if (preparedSearchQuery.params.containsKey("explain")) parseExplanation(rawHit.obj("_explanation")) else null, + explanation = if (preparedSearchQuery.params.containsKey("explain")) + parseExplanation(rawHit.obj("_explanation")) + else + null, ) } diff --git a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/SearchQueryTests.kt b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/SearchQueryTests.kt index 4bb04077c0..4876d218cd 100644 --- a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/SearchQueryTests.kt +++ b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/SearchQueryTests.kt @@ -9,12 +9,12 @@ import dev.evo.elasticmagic.aggs.NestedAgg import dev.evo.elasticmagic.aggs.SingleBucketAggResult import dev.evo.elasticmagic.aggs.TermsAgg import dev.evo.elasticmagic.aggs.TermsAggResult +import dev.evo.elasticmagic.bulk.DocSourceAndMeta +import dev.evo.elasticmagic.bulk.withActionMeta import dev.evo.elasticmagic.doc.BaseDocSource import dev.evo.elasticmagic.doc.BoundField import dev.evo.elasticmagic.doc.DocSource import dev.evo.elasticmagic.doc.Document -import dev.evo.elasticmagic.bulk.DocSourceAndMeta -import dev.evo.elasticmagic.bulk.withActionMeta import dev.evo.elasticmagic.doc.DynDocSource import dev.evo.elasticmagic.doc.SubDocument import dev.evo.elasticmagic.doc.enum @@ -26,25 +26,22 @@ import dev.evo.elasticmagic.query.Sort import dev.evo.elasticmagic.query.match import dev.evo.elasticmagic.transport.ElasticsearchException import dev.evo.elasticmagic.types.KeywordType - import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import io.kotest.matchers.booleans.shouldBeTrue import io.kotest.matchers.booleans.shouldBeFalse +import io.kotest.matchers.booleans.shouldBeTrue import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.floats.shouldBeGreaterThan import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull -import io.kotest.matchers.floats.shouldBeGreaterThan +import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldHaveMinLength import io.kotest.matchers.types.shouldBeInstanceOf - import kotlinx.datetime.Instant import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone import kotlinx.datetime.atStartOfDayIn import kotlinx.datetime.toInstant - import kotlin.test.Test enum class OrderStatus(val id: Int) : ToValue { @@ -655,10 +652,10 @@ class SearchQueryTests : ElasticsearchTestBase() { .execute(index) searchResult.hits.size shouldBe 4 - searchResult.hits.flatMap { hit -> hit.fields[dayOfWeekField]!! } shouldBe listOf( + searchResult.hits.flatMap { hit -> hit.fields[dayOfWeekField] } shouldBe listOf( "Thursday", "Thursday", "Tuesday", "Wednesday" ) - searchResult.hits.flatMap { hit -> hit.fields[statusStrField]!! } shouldBe listOf( + searchResult.hits.flatMap { hit -> hit.fields[statusStrField] } shouldBe listOf( "1", "1", "0", "0" ) val daysOfWeekAgg = searchResult.agg>("days_of_week") From 13586772989d5a01d8020095ea0b213ab717ce66 Mon Sep 17 00:00:00 2001 From: "a.usenko" Date: Mon, 24 Jul 2023 14:29:05 +0300 Subject: [PATCH 6/6] fix mr --- .../evo/elasticmagic/compile/SearchQueryCompiler.kt | 5 +---- .../kotlin/dev/evo/elasticmagic/ExplanationTest.kt | 13 +++++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt index 86f1f4c376..42a5a0cb6d 100644 --- a/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt +++ b/elasticmagic/src/commonMain/kotlin/dev/evo/elasticmagic/compile/SearchQueryCompiler.kt @@ -296,10 +296,7 @@ open class SearchQueryCompiler( sort = sort.ifEmpty { null }, source = source, fields = fields, - explanation = if (preparedSearchQuery.params.containsKey("explain")) - parseExplanation(rawHit.obj("_explanation")) - else - null, + explanation = rawHit.objOrNull("_explanation")?.let(::parseExplanation), ) } diff --git a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt index e394e80b58..5af63d9805 100644 --- a/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt +++ b/integ-tests/src/commonTest/kotlin/dev/evo/elasticmagic/ExplanationTest.kt @@ -11,7 +11,7 @@ import io.kotest.matchers.shouldNotBe import kotlin.test.Test class ExplanationTest : ElasticsearchTestBase() { - override val indexName = "explanation-test" + override val indexName = "explanation" class StringField(name: String) : BoundField( name, @@ -39,8 +39,10 @@ class ExplanationTest : ElasticsearchTestBase() { val explanations = result.hits.mapNotNull { it.explanation } explanations.size shouldBe 8 - explanations.map { it.details shouldBe emptyList() } - + explanations.map { + it.value shouldNotBe 1.0f + it.details shouldBe emptyList() + } } } @@ -53,7 +55,10 @@ class ExplanationTest : ElasticsearchTestBase() { val explanations = result.hits.mapNotNull { it.explanation } explanations.size shouldBe 5 - explanations.map { it.details.size shouldNotBe 0 } + explanations.map { + it.description shouldBe "sum of:" + it.details.size shouldNotBe 0 + } } }