diff --git a/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequest.kt b/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequest.kt index 4be6aa7..8078981 100644 --- a/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequest.kt +++ b/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequest.kt @@ -27,7 +27,9 @@ data class SearchRequest @JvmOverloads constructor( @JsonProperty("min_score") val minScore: Double? = null, @JsonProperty("search_after") - val searchAfter: List? = null + val searchAfter: List? = null, + @JsonProperty("_source") + val source: SourceFilter<*>? = null ) { class Builder { @@ -41,6 +43,7 @@ data class SearchRequest @JvmOverloads constructor( private var sort: MutableList = mutableListOf() private var minScore: Double? = null private var searchAfter: MutableList = mutableListOf() + private var source: SourceFilter<*>? = null fun query(query: Query) = apply { this.query = query } fun scriptField(name: String, script: Script) = apply { this.scriptFields.add(ScriptField(name, script)) } @@ -56,6 +59,7 @@ data class SearchRequest @JvmOverloads constructor( fun minScore(minScore: Double) = apply { this.minScore = minScore } fun searchAfter(vararg searchAfter: Any) = apply { this.searchAfter.addAll(searchAfter) } fun searchAfter(searchAfter: List) = apply { this.searchAfter.addAll(searchAfter) } + fun source(source: SourceFilter<*>) = apply { this.source = source } fun build() = SearchRequest( query = query ?: error("Query can't be null"), @@ -67,7 +71,8 @@ data class SearchRequest @JvmOverloads constructor( suggest = if (suggest.isEmpty()) null else suggest.toMap(), sort = if (sort.isEmpty()) null else sort.toList(), minScore = minScore, - searchAfter = if (searchAfter.isEmpty()) null else searchAfter.toList() + searchAfter = if (searchAfter.isEmpty()) null else searchAfter.toList(), + source = source ) } @@ -75,4 +80,4 @@ data class SearchRequest @JvmOverloads constructor( @JvmStatic fun builder() = Builder() } -} \ No newline at end of file +} diff --git a/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SourceFilter.kt b/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SourceFilter.kt new file mode 100644 index 0000000..071d77c --- /dev/null +++ b/java/src/main/kotlin/org/taymyr/lagom/elasticsearch/search/dsl/SourceFilter.kt @@ -0,0 +1,31 @@ +package org.taymyr.lagom.elasticsearch.search.dsl + +import com.fasterxml.jackson.annotation.JsonValue + +/** + * See [[https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#source-filtering]] + */ +sealed class SourceFilter(open val value: T) { + data class Inclusion(@get:JsonValue override val value: Boolean) : SourceFilter(value) + + data class SinglePath(@get:JsonValue override val value: String) : SourceFilter(value) + + data class MultiPath(@get:JsonValue override val value: List) : SourceFilter>(value) + + data class IncExc(val includes: List, val excludes: List) + + data class IncludeExclude(@get:JsonValue override val value: IncExc) : SourceFilter(value) + + companion object { + @JvmField + val EXCLUDE_SOURCE = Inclusion(false) + @JvmField + val INCLUDE_SOURCE = Inclusion(true) + @JvmStatic + fun singlePath(value: String) = SinglePath(value) + @JvmStatic + fun multiPath(value: List) = MultiPath(value) + @JvmStatic + fun multiPath(includes: List, excludes: List) = IncludeExclude(IncExc(includes, excludes)) + } +} diff --git a/java/src/test/java/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequestTest.java b/java/src/test/java/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequestTest.java index d69ca6a..1953ccc 100644 --- a/java/src/test/java/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequestTest.java +++ b/java/src/test/java/org/taymyr/lagom/elasticsearch/search/dsl/SearchRequestTest.java @@ -1,6 +1,5 @@ package org.taymyr.lagom.elasticsearch.search.dsl; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -167,4 +166,48 @@ void shouldThrowExceptionForIncorrectRequest() { .isInstanceOf(IllegalStateException.class) .hasMessage("Query can't be null"); } + + @Test + @DisplayName("source filter serialization") + void shouldSerializeSourceFilter() { + SearchRequest request = SearchRequest.builder() + .source(SourceFilter.EXCLUDE_SOURCE) + .query(IdsQuery.of("1")) + .build(); + String actual = serializeRequest(request, SearchRequest.class); + String expected = resourceAsString("org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_excluded.json"); + assertThatJson(actual).isEqualTo(expected); + + request = SearchRequest.builder() + .source(SourceFilter.INCLUDE_SOURCE) + .query(IdsQuery.of("1")) + .build(); + actual = serializeRequest(request, SearchRequest.class); + expected = resourceAsString("org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_included.json"); + assertThatJson(actual).isEqualTo(expected); + + request = SearchRequest.builder() + .source(SourceFilter.singlePath("order.client.*")) + .query(IdsQuery.of("1")) + .build(); + actual = serializeRequest(request, SearchRequest.class); + expected = resourceAsString("org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_single_path.json"); + assertThatJson(actual).isEqualTo(expected); + + request = SearchRequest.builder() + .source(SourceFilter.multiPath(asList("order.client.*", "order.price.*"))) + .query(IdsQuery.of("1")) + .build(); + actual = serializeRequest(request, SearchRequest.class); + expected = resourceAsString("org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_multi_path.json"); + assertThatJson(actual).isEqualTo(expected); + + request = SearchRequest.builder() + .source(SourceFilter.multiPath(asList("order.client.*", "order.seller.*"), asList( "order.price.*"))) + .query(IdsQuery.of("1")) + .build(); + actual = serializeRequest(request, SearchRequest.class); + expected = resourceAsString("org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_includes_excludes.json"); + assertThatJson(actual).isEqualTo(expected); + } } diff --git a/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_excluded.json b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_excluded.json new file mode 100644 index 0000000..cd7d88e --- /dev/null +++ b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_excluded.json @@ -0,0 +1,10 @@ +{ + "_source": false, + "query": { + "ids": { + "values": [ + "1" + ] + } + } +} diff --git a/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_included.json b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_included.json new file mode 100644 index 0000000..a00808d --- /dev/null +++ b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_included.json @@ -0,0 +1,10 @@ +{ + "_source": true, + "query": { + "ids": { + "values": [ + "1" + ] + } + } +} diff --git a/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_includes_excludes.json b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_includes_excludes.json new file mode 100644 index 0000000..403fd1d --- /dev/null +++ b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_includes_excludes.json @@ -0,0 +1,13 @@ +{ + "_source": { + "includes": ["order.client.*", "order.seller.*"], + "excludes": ["order.price.*"] + }, + "query": { + "ids": { + "values": [ + "1" + ] + } + } +} diff --git a/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_multi_path.json b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_multi_path.json new file mode 100644 index 0000000..c8cdee1 --- /dev/null +++ b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_multi_path.json @@ -0,0 +1,10 @@ +{ + "_source": ["order.client.*", "order.price.*"], + "query": { + "ids": { + "values": [ + "1" + ] + } + } +} diff --git a/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_single_path.json b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_single_path.json new file mode 100644 index 0000000..490903e --- /dev/null +++ b/java/src/test/resources/org/taymyr/lagom/elasticsearch/search/dsl/query/source/source_single_path.json @@ -0,0 +1,10 @@ +{ + "_source": "order.client.*", + "query": { + "ids": { + "values": [ + "1" + ] + } + } +}