From 866907a515dcadf433a1d2400a8f428f290a348c Mon Sep 17 00:00:00 2001 From: Laura Trotta <153528055+l-trotta@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:37:18 +0200 Subject: [PATCH] Source shortcut support (#1260) * supporting _source shortcut * regen --- .../core/search/SourceConfig.java | 29 ++++++++++++++----- .../spec_issues/SpecIssuesTest.java | 24 +++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java index db59af2dd5..c4053b4068 100644 --- a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java +++ b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java @@ -25,15 +25,17 @@ import co.elastic.clients.json.JsonpSerializable; import co.elastic.clients.json.JsonpUtils; import co.elastic.clients.json.ObjectDeserializer; -import co.elastic.clients.json.UnionDeserializer; import co.elastic.clients.util.ApiTypeHelper; import co.elastic.clients.util.ObjectBuilder; import co.elastic.clients.util.ObjectBuilderBase; import co.elastic.clients.util.TaggedUnion; import co.elastic.clients.util.TaggedUnionUtils; import jakarta.json.stream.JsonGenerator; +import jakarta.json.stream.JsonParser; import java.lang.Boolean; import java.lang.Object; +import java.util.EnumSet; +import java.util.List; import java.util.Objects; import java.util.function.Function; import javax.annotation.Nullable; @@ -181,12 +183,23 @@ public SourceConfig build() { } - private static JsonpDeserializer buildSourceConfigDeserializer() { - return new UnionDeserializer.Builder(SourceConfig::new, false) - .addMember(Kind.Filter, SourceFilter._DESERIALIZER) - .addMember(Kind.Fetch, JsonpDeserializer.booleanDeserializer()).build(); - } - public static final JsonpDeserializer _DESERIALIZER = JsonpDeserializer - .lazy(SourceConfig::buildSourceConfigDeserializer); + .lazy(() -> JsonpDeserializer.of(EnumSet.of(JsonParser.Event.START_OBJECT, JsonParser.Event.START_ARRAY, + JsonParser.Event.VALUE_TRUE, JsonParser.Event.VALUE_FALSE), (parser, mapper, event) -> { + return switch (event) { + case VALUE_TRUE -> SourceConfig.of(b -> b.fetch(true)); + case VALUE_FALSE -> SourceConfig.of(b -> b.fetch(false)); + case START_ARRAY -> { + List includes = JsonpDeserializer + .arrayDeserializer(JsonpDeserializer.stringDeserializer()) + .deserialize(parser, mapper, event); + yield SourceConfig.of(b -> b.filter(f -> f.includes(includes))); + } + case START_OBJECT -> { + SourceFilter filter = SourceFilter._DESERIALIZER.deserialize(parser, mapper, event); + yield SourceConfig.of(b -> b.filter(filter)); + } + default -> null; + }; + })); } diff --git a/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java b/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java index a36ba6a4b9..9dc69bf17d 100644 --- a/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java +++ b/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java @@ -46,6 +46,8 @@ import java.io.InputStream; import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; /** * Test issues related to the API specifications. @@ -54,6 +56,28 @@ */ public class SpecIssuesTest extends ModelTestCase { + @Test + public void i1245_sourceAsArray() { + // "_source" also accepts an array of field names as a shortcut for SourceFilter.includes + SearchRequest array = fromJson("{\"_source\":[\"date\",\"distributor\"]}", SearchRequest.class); + assertTrue(array.source().isFilter()); + assertEquals(Arrays.asList("date", "distributor"), array.source().filter().includes()); + + // The object form still works, with all SourceFilter fields set + SearchRequest object = fromJson( + "{\"_source\":{\"includes\":[\"date\",\"distributor\"],\"excludes\":[\"secret\"],\"exclude_vectors\":true}}", + SearchRequest.class); + assertTrue(object.source().isFilter()); + assertEquals(Arrays.asList("date", "distributor"), object.source().filter().includes()); + assertEquals(Collections.singletonList("secret"), object.source().filter().excludes()); + assertTrue(object.source().filter().excludeVectors()); + + // The boolean form still works + SearchRequest bool = fromJson("{\"_source\":false}", SearchRequest.class); + assertTrue(bool.source().isFetch()); + assertFalse(bool.source().fetch()); + } + @Test public void i0328_charFilter() throws Exception { // Both mappings and mappings_path are optional