Polishing.

This commit is contained in:
Peter-Josef Meisch 2024-04-16 20:40:53 +02:00
parent 2d5f8e8219
commit a16782ec73
No known key found for this signature in database
GPG Key ID: DE108246970C7708
8 changed files with 353 additions and 360 deletions

View File

@ -10,6 +10,7 @@
* Add support for multi search template API. * Add support for multi search template API.
* Add support for SpEL in @Query. * Add support for SpEL in @Query.
* Add support for field aliases in the index mapping. * Add support for field aliases in the index mapping.
* Add support for has_child and has_parent queries.
[[new-features.5-2-0]] [[new-features.5-2-0]]
== New in Spring Data Elasticsearch 5.2 == New in Spring Data Elasticsearch 5.2

View File

@ -15,57 +15,56 @@
*/ */
package org.springframework.data.elasticsearch.client.elc; package org.springframework.data.elasticsearch.client.elc;
import java.util.function.Consumer;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import java.util.function.Consumer;
/** /**
* An abstract class that serves as a base for query processors. * An abstract class that serves as a base for query processors. It provides a common interface and basic functionality
* It provides a common interface and basic functionality for query processing. * for query processing.
* *
* @author Aouichaoui Youssef * @author Aouichaoui Youssef
* @since 5.3 * @since 5.3
*/ */
public abstract class AbstractQueryProcessor { public abstract class AbstractQueryProcessor {
/** /**
* Convert a spring-data-elasticsearch {@literal query} to an Elasticsearch {@literal query}. * Convert a spring-data-elasticsearch {@literal query} to an Elasticsearch {@literal query}.
* *
* @param query spring-data-elasticsearch {@literal query}. * @param query spring-data-elasticsearch {@literal query}.
* @param queryConverter correct mapped field names and the values to the converted values. * @param queryConverter correct mapped field names and the values to the converted values.
* @return an Elasticsearch {@literal query}. * @return an Elasticsearch {@literal query}.
*/ */
@Nullable @Nullable
static co.elastic.clients.elasticsearch._types.query_dsl.Query getEsQuery(@Nullable Query query, static co.elastic.clients.elasticsearch._types.query_dsl.Query getEsQuery(@Nullable Query query,
@Nullable Consumer<Query> queryConverter) { @Nullable Consumer<Query> queryConverter) {
if (query == null) { if (query == null) {
return null; return null;
} }
if (queryConverter != null) { if (queryConverter != null) {
queryConverter.accept(query); queryConverter.accept(query);
} }
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = null; co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = null;
if (query instanceof CriteriaQuery criteriaQuery) { if (query instanceof CriteriaQuery criteriaQuery) {
esQuery = CriteriaQueryProcessor.createQuery(criteriaQuery.getCriteria()); esQuery = CriteriaQueryProcessor.createQuery(criteriaQuery.getCriteria());
} else if (query instanceof StringQuery stringQuery) { } else if (query instanceof StringQuery stringQuery) {
esQuery = Queries.wrapperQueryAsQuery(stringQuery.getSource()); esQuery = Queries.wrapperQueryAsQuery(stringQuery.getSource());
} else if (query instanceof NativeQuery nativeQuery) { } else if (query instanceof NativeQuery nativeQuery) {
if (nativeQuery.getQuery() != null) { if (nativeQuery.getQuery() != null) {
esQuery = nativeQuery.getQuery(); esQuery = nativeQuery.getQuery();
} else if (nativeQuery.getSpringDataQuery() != null) { } else if (nativeQuery.getSpringDataQuery() != null) {
esQuery = getEsQuery(nativeQuery.getSpringDataQuery(), queryConverter); esQuery = getEsQuery(nativeQuery.getSpringDataQuery(), queryConverter);
} }
} else { } else {
throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName()); throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName());
} }
return esQuery; return esQuery;
} }
} }

View File

@ -16,7 +16,7 @@
package org.springframework.data.elasticsearch.client.elc; package org.springframework.data.elasticsearch.client.elc;
import static org.springframework.data.elasticsearch.client.elc.Queries.*; import static org.springframework.data.elasticsearch.client.elc.Queries.*;
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.scoreMode; import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
import static org.springframework.util.StringUtils.*; import static org.springframework.util.StringUtils.*;
import co.elastic.clients.elasticsearch._types.FieldValue; import co.elastic.clients.elasticsearch._types.FieldValue;
@ -32,12 +32,10 @@ import java.util.List;
import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Field; import org.springframework.data.elasticsearch.core.query.Field;
import org.springframework.data.elasticsearch.core.query.HasChildQuery; import org.springframework.data.elasticsearch.core.query.HasChildQuery;
import org.springframework.data.elasticsearch.core.query.HasParentQuery; import org.springframework.data.elasticsearch.core.query.HasParentQuery;
import org.springframework.data.elasticsearch.core.query.InnerHitsQuery; import org.springframework.data.elasticsearch.core.query.InnerHitsQuery;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -357,27 +355,25 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
.query(getEsQuery(query.getQuery(), null)) .query(getEsQuery(query.getQuery(), null))
.innerHits(getInnerHits(query.getInnerHitsQuery())) .innerHits(getInnerHits(query.getInnerHitsQuery()))
.ignoreUnmapped(query.getIgnoreUnmapped()) .ignoreUnmapped(query.getIgnoreUnmapped())
.minChildren(query.getMinChildren()) .minChildren(query.getMinChildren())
.maxChildren(query.getMaxChildren()) .maxChildren(query.getMaxChildren())
.scoreMode(scoreMode(query.getScoreMode())) .scoreMode(scoreMode(query.getScoreMode())));
);
} else { } else {
throw new CriteriaQueryException("value for " + fieldName + " is not a has_child query"); throw new CriteriaQueryException("value for " + fieldName + " is not a has_child query");
} }
break; break;
case HAS_PARENT: case HAS_PARENT:
if (value instanceof HasParentQuery query) { if (value instanceof HasParentQuery query) {
queryBuilder.hasParent(hpb -> hpb queryBuilder.hasParent(hpb -> hpb
.parentType(query.getParentType()) .parentType(query.getParentType())
.query(getEsQuery(query.getQuery(), null)) .query(getEsQuery(query.getQuery(), null))
.innerHits(getInnerHits(query.getInnerHitsQuery())) .innerHits(getInnerHits(query.getInnerHitsQuery()))
.ignoreUnmapped(query.getIgnoreUnmapped()) .ignoreUnmapped(query.getIgnoreUnmapped())
.score(query.getScore()) .score(query.getScore()));
); } else {
} else { throw new CriteriaQueryException("value for " + fieldName + " is not a has_parent query");
throw new CriteriaQueryException("value for " + fieldName + " is not a has_parent query"); }
} break;
break;
default: default:
throw new CriteriaQueryException("Could not build query for " + entry); throw new CriteriaQueryException("Could not build query for " + entry);
} }
@ -432,19 +428,19 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
return sb.toString(); return sb.toString();
} }
/** /**
* Convert a spring-data-elasticsearch {@literal inner_hits} to an Elasticsearch {@literal inner_hits} query. * Convert a spring-data-elasticsearch {@literal inner_hits} to an Elasticsearch {@literal inner_hits} query.
* *
* @param query spring-data-elasticsearch {@literal inner_hits}. * @param query spring-data-elasticsearch {@literal inner_hits}.
* @return an Elasticsearch {@literal inner_hits} query. * @return an Elasticsearch {@literal inner_hits} query.
*/ */
@Nullable @Nullable
private static InnerHits getInnerHits(@Nullable InnerHitsQuery query) { private static InnerHits getInnerHits(@Nullable InnerHitsQuery query) {
if (query == null) { if (query == null) {
return null; return null;
} }
return InnerHits.of(iqb -> iqb.from(query.getFrom()).size(query.getSize()).name(query.getName())); return InnerHits.of(iqb -> iqb.from(query.getFrom()).size(query.getSize()).name(query.getName()));
} }
} }

View File

@ -1007,8 +1007,7 @@ public class Criteria {
/** /**
* @since 5.3 * @since 5.3
*/ */
HAS_CHILD, HAS_CHILD, HAS_PARENT;
HAS_PARENT;
/** /**
* @return true if this key does not have an associated value * @return true if this key does not have an associated value

View File

@ -22,182 +22,183 @@ import org.springframework.util.Assert;
* Defines a has_child request. * Defines a has_child request.
* *
* @author Aouichaoui Youssef * @author Aouichaoui Youssef
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html">docs</a> * @see <a href=
* "https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html">docs</a>
* @since 5.3 * @since 5.3
*/ */
public class HasChildQuery { public class HasChildQuery {
/** /**
* Name of the child relationship mapped for the join field. * Name of the child relationship mapped for the join field.
*/ */
private final String type; private final String type;
/** /**
* Query that specifies the documents to run on child documents of the {@link #type} field. * Query that specifies the documents to run on child documents of the {@link #type} field.
*/ */
private final Query query; private final Query query;
/** /**
* Indicates whether to ignore an unmapped {@link #type} and not return any documents instead of an error. * Indicates whether to ignore an unmapped {@link #type} and not return any documents instead of an error. Default,
* Default, this is set to {@code false}. * this is set to {@code false}.
*/ */
@Nullable private final Boolean ignoreUnmapped; @Nullable private final Boolean ignoreUnmapped;
/** /**
* The Maximum number of child documents that match the {@link #query} allowed for a returned parent document. * The Maximum number of child documents that match the {@link #query} allowed for a returned parent document. If the
* If the parent document exceeds this limit, it is excluded from the search results. * parent document exceeds this limit, it is excluded from the search results.
*/ */
@Nullable private final Integer maxChildren; @Nullable private final Integer maxChildren;
/** /**
* Minimum number of child documents that match the query required to match the {@link #query} for a returned parent document. * Minimum number of child documents that match the query required to match the {@link #query} for a returned parent
* If the parent document does not meet this limit, it is excluded from the search results. * document. If the parent document does not meet this limit, it is excluded from the search results.
*/ */
@Nullable private final Integer minChildren; @Nullable private final Integer minChildren;
/** /**
* Indicates how scores for matching child documents affect the root parent documents relevance score. * Indicates how scores for matching child documents affect the root parent documents relevance score.
*/ */
@Nullable private final ScoreMode scoreMode; @Nullable private final ScoreMode scoreMode;
/** /**
* Obtaining nested objects and documents that have a parent-child relationship. * Obtaining nested objects and documents that have a parent-child relationship.
*/ */
@Nullable private final InnerHitsQuery innerHitsQuery; @Nullable private final InnerHitsQuery innerHitsQuery;
public static Builder builder(String type) { public static Builder builder(String type) {
return new Builder(type); return new Builder(type);
} }
private HasChildQuery(Builder builder) { private HasChildQuery(Builder builder) {
this.type = builder.type; this.type = builder.type;
this.query = builder.query; this.query = builder.query;
this.innerHitsQuery = builder.innerHitsQuery; this.innerHitsQuery = builder.innerHitsQuery;
this.ignoreUnmapped = builder.ignoreUnmapped; this.ignoreUnmapped = builder.ignoreUnmapped;
this.maxChildren = builder.maxChildren; this.maxChildren = builder.maxChildren;
this.minChildren = builder.minChildren; this.minChildren = builder.minChildren;
this.scoreMode = builder.scoreMode; this.scoreMode = builder.scoreMode;
} }
public String getType() { public String getType() {
return type; return type;
} }
public Query getQuery() { public Query getQuery() {
return query; return query;
} }
@Nullable @Nullable
public Boolean getIgnoreUnmapped() { public Boolean getIgnoreUnmapped() {
return ignoreUnmapped; return ignoreUnmapped;
} }
@Nullable @Nullable
public Integer getMaxChildren() { public Integer getMaxChildren() {
return maxChildren; return maxChildren;
} }
@Nullable @Nullable
public Integer getMinChildren() { public Integer getMinChildren() {
return minChildren; return minChildren;
} }
@Nullable @Nullable
public ScoreMode getScoreMode() { public ScoreMode getScoreMode() {
return scoreMode; return scoreMode;
} }
@Nullable @Nullable
public InnerHitsQuery getInnerHitsQuery() { public InnerHitsQuery getInnerHitsQuery() {
return innerHitsQuery; return innerHitsQuery;
} }
public enum ScoreMode { public enum ScoreMode {
Default, Avg, Max, Min, Sum Default, Avg, Max, Min, Sum
} }
public static final class Builder { public static final class Builder {
private final String type; private final String type;
private Query query; private Query query;
@Nullable private Boolean ignoreUnmapped; @Nullable private Boolean ignoreUnmapped;
@Nullable private Integer maxChildren; @Nullable private Integer maxChildren;
@Nullable private Integer minChildren; @Nullable private Integer minChildren;
@Nullable private ScoreMode scoreMode; @Nullable private ScoreMode scoreMode;
@Nullable private InnerHitsQuery innerHitsQuery; @Nullable private InnerHitsQuery innerHitsQuery;
private Builder(String type) { private Builder(String type) {
Assert.notNull(type, "type must not be null"); Assert.notNull(type, "type must not be null");
this.type = type; this.type = type;
} }
/** /**
* Query that specifies the documents to run on child documents of the {@link #type} field. * Query that specifies the documents to run on child documents of the {@link #type} field.
*/ */
public Builder withQuery(Query query) { public Builder withQuery(Query query) {
this.query = query; this.query = query;
return this; return this;
} }
/** /**
* Indicates whether to ignore an unmapped {@link #type} and not return any documents instead of an error. * Indicates whether to ignore an unmapped {@link #type} and not return any documents instead of an error. Default,
* Default, this is set to {@code false}. * this is set to {@code false}.
*/ */
public Builder withIgnoreUnmapped(@Nullable Boolean ignoreUnmapped) { public Builder withIgnoreUnmapped(@Nullable Boolean ignoreUnmapped) {
this.ignoreUnmapped = ignoreUnmapped; this.ignoreUnmapped = ignoreUnmapped;
return this; return this;
} }
/** /**
* The Maximum number of child documents that match the {@link #query} allowed for a returned parent document. * The Maximum number of child documents that match the {@link #query} allowed for a returned parent document. If
* If the parent document exceeds this limit, it is excluded from the search results. * the parent document exceeds this limit, it is excluded from the search results.
*/ */
public Builder withMaxChildren(@Nullable Integer maxChildren) { public Builder withMaxChildren(@Nullable Integer maxChildren) {
this.maxChildren = maxChildren; this.maxChildren = maxChildren;
return this; return this;
} }
/** /**
* Minimum number of child documents that match the query required to match the {@link #query} for a returned parent document. * Minimum number of child documents that match the query required to match the {@link #query} for a returned parent
* If the parent document does not meet this limit, it is excluded from the search results. * document. If the parent document does not meet this limit, it is excluded from the search results.
*/ */
public Builder withMinChildren(@Nullable Integer minChildren) { public Builder withMinChildren(@Nullable Integer minChildren) {
this.minChildren = minChildren; this.minChildren = minChildren;
return this; return this;
} }
/** /**
* Indicates how scores for matching child documents affect the root parent documents relevance score. * Indicates how scores for matching child documents affect the root parent documents relevance score.
*/ */
public Builder withScoreMode(@Nullable ScoreMode scoreMode) { public Builder withScoreMode(@Nullable ScoreMode scoreMode) {
this.scoreMode = scoreMode; this.scoreMode = scoreMode;
return this; return this;
} }
/** /**
* Obtaining nested objects and documents that have a parent-child relationship. * Obtaining nested objects and documents that have a parent-child relationship.
*/ */
public Builder withInnerHitsQuery(@Nullable InnerHitsQuery innerHitsQuery) { public Builder withInnerHitsQuery(@Nullable InnerHitsQuery innerHitsQuery) {
this.innerHitsQuery = innerHitsQuery; this.innerHitsQuery = innerHitsQuery;
return this; return this;
} }
public HasChildQuery build() { public HasChildQuery build() {
Assert.notNull(query, "query must not be null."); Assert.notNull(query, "query must not be null.");
return new HasChildQuery(this); return new HasChildQuery(this);
} }
} }
} }

View File

@ -22,119 +22,120 @@ import org.springframework.util.Assert;
* Defines a has_parent request. * Defines a has_parent request.
* *
* @author Aouichaoui Youssef * @author Aouichaoui Youssef
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html">docs</a> * @see <a href=
* "https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html">docs</a>
* @since 5.3 * @since 5.3
*/ */
public class HasParentQuery { public class HasParentQuery {
/** /**
* Name of the parent relationship mapped for the join field. * Name of the parent relationship mapped for the join field.
*/ */
private final String parentType; private final String parentType;
/** /**
* Query that specifies the documents to run on parent documents of the {@link #parentType} field. * Query that specifies the documents to run on parent documents of the {@link #parentType} field.
*/ */
private final Query query; private final Query query;
/** /**
* Indicates whether the relevance score of a matching parent document is aggregated into its child documents. * Indicates whether the relevance score of a matching parent document is aggregated into its child documents.
* Default, this is set to {@code false}. * Default, this is set to {@code false}.
*/ */
@Nullable private final Boolean score; @Nullable private final Boolean score;
/** /**
* Indicates whether to ignore an unmapped {@link #parentType} and not return any documents instead of an error. * Indicates whether to ignore an unmapped {@link #parentType} and not return any documents instead of an error.
* Default, this is set to {@code false}. * Default, this is set to {@code false}.
*/ */
@Nullable private final Boolean ignoreUnmapped; @Nullable private final Boolean ignoreUnmapped;
/** /**
* Obtaining nested objects and documents that have a parent-child relationship. * Obtaining nested objects and documents that have a parent-child relationship.
*/ */
@Nullable private final InnerHitsQuery innerHitsQuery; @Nullable private final InnerHitsQuery innerHitsQuery;
public static Builder builder(String parentType) { public static Builder builder(String parentType) {
return new Builder(parentType); return new Builder(parentType);
} }
private HasParentQuery(Builder builder) { private HasParentQuery(Builder builder) {
this.parentType = builder.parentType; this.parentType = builder.parentType;
this.query = builder.query; this.query = builder.query;
this.innerHitsQuery = builder.innerHitsQuery; this.innerHitsQuery = builder.innerHitsQuery;
this.score = builder.score; this.score = builder.score;
this.ignoreUnmapped = builder.ignoreUnmapped; this.ignoreUnmapped = builder.ignoreUnmapped;
} }
public String getParentType() { public String getParentType() {
return parentType; return parentType;
} }
public Query getQuery() { public Query getQuery() {
return query; return query;
} }
@Nullable @Nullable
public Boolean getScore() { public Boolean getScore() {
return score; return score;
} }
@Nullable @Nullable
public Boolean getIgnoreUnmapped() { public Boolean getIgnoreUnmapped() {
return ignoreUnmapped; return ignoreUnmapped;
} }
@Nullable @Nullable
public InnerHitsQuery getInnerHitsQuery() { public InnerHitsQuery getInnerHitsQuery() {
return innerHitsQuery; return innerHitsQuery;
} }
public static class Builder { public static class Builder {
private final String parentType; private final String parentType;
private Query query; private Query query;
@Nullable private Boolean score; @Nullable private Boolean score;
@Nullable private Boolean ignoreUnmapped; @Nullable private Boolean ignoreUnmapped;
@Nullable private InnerHitsQuery innerHitsQuery; @Nullable private InnerHitsQuery innerHitsQuery;
private Builder(String parentType) { private Builder(String parentType) {
Assert.notNull(parentType, "parent_type must not be null."); Assert.notNull(parentType, "parent_type must not be null.");
this.parentType = parentType; this.parentType = parentType;
} }
public Builder withQuery(Query query) { public Builder withQuery(Query query) {
this.query = query; this.query = query;
return this; return this;
} }
public Builder withScore(@Nullable Boolean score) { public Builder withScore(@Nullable Boolean score) {
this.score = score; this.score = score;
return this; return this;
} }
public Builder withIgnoreUnmapped(@Nullable Boolean ignoreUnmapped) { public Builder withIgnoreUnmapped(@Nullable Boolean ignoreUnmapped) {
this.ignoreUnmapped = ignoreUnmapped; this.ignoreUnmapped = ignoreUnmapped;
return this; return this;
} }
/** /**
* Obtaining nested objects and documents that have a parent-child relationship. * Obtaining nested objects and documents that have a parent-child relationship.
*/ */
public Builder withInnerHitsQuery(@Nullable InnerHitsQuery innerHitsQuery) { public Builder withInnerHitsQuery(@Nullable InnerHitsQuery innerHitsQuery) {
this.innerHitsQuery = innerHitsQuery; this.innerHitsQuery = innerHitsQuery;
return this; return this;
} }
public HasParentQuery build() { public HasParentQuery build() {
Assert.notNull(query, "query must not be null."); Assert.notNull(query, "query must not be null.");
return new HasParentQuery(this); return new HasParentQuery(this);
} }
} }
} }

View File

@ -25,84 +25,83 @@ import org.springframework.lang.Nullable;
* @since 5.3 * @since 5.3
*/ */
public class InnerHitsQuery { public class InnerHitsQuery {
/** /**
* The name to be used for the particular inner hit definition in the response. * The name to be used for the particular inner hit definition in the response.
*/ */
@Nullable private final String name; @Nullable private final String name;
/** /**
* The maximum number of hits to return. * The maximum number of hits to return.
*/ */
@Nullable private final Integer size; @Nullable private final Integer size;
/** /**
* The offset from where the first hit to fetch. * The offset from where the first hit to fetch.
*/ */
@Nullable private final Integer from; @Nullable private final Integer from;
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
private InnerHitsQuery(Builder builder) { private InnerHitsQuery(Builder builder) {
this.name = builder.name; this.name = builder.name;
this.from = builder.from; this.from = builder.from;
this.size = builder.size; this.size = builder.size;
} }
@Nullable @Nullable
public String getName() { public String getName() {
return name; return name;
} }
@Nullable @Nullable
public Integer getSize() { public Integer getSize() {
return size; return size;
} }
@Nullable @Nullable
public Integer getFrom() { public Integer getFrom() {
return from; return from;
} }
public static final class Builder { public static final class Builder {
@Nullable private String name; @Nullable private String name;
@Nullable private Integer size; @Nullable private Integer size;
@Nullable private Integer from; @Nullable private Integer from;
private Builder() { private Builder() {}
}
/** /**
* The name to be used for the particular inner hit definition in the response. * The name to be used for the particular inner hit definition in the response.
*/ */
public Builder withName(@Nullable String name) { public Builder withName(@Nullable String name) {
this.name = name; this.name = name;
return this; return this;
} }
/** /**
* The maximum number of hits to return. * The maximum number of hits to return.
*/ */
public Builder withSize(@Nullable Integer size) { public Builder withSize(@Nullable Integer size) {
this.size = size; this.size = size;
return this; return this;
} }
/** /**
* The offset from where the first hit to fetch. * The offset from where the first hit to fetch.
*/ */
public Builder withFrom(@Nullable Integer from) { public Builder withFrom(@Nullable Integer from) {
this.from = from; this.from = from;
return this; return this;
} }
public InnerHitsQuery build() { public InnerHitsQuery build() {
return new InnerHitsQuery(this); return new InnerHitsQuery(this);
} }
} }
} }

View File

@ -5013,21 +5013,18 @@ public abstract class ElasticsearchIntegrationTests {
@Document(indexName = "#{@indexNameProvider.indexName()}-join") @Document(indexName = "#{@indexNameProvider.indexName()}-join")
private static class RootEntity { private static class RootEntity {
@Id @Id private String id;
private String id;
@Field(type = FieldType.Object) @Field(type = FieldType.Object) private Child child;
private Child child;
@Field(type = FieldType.Object) @Field(type = FieldType.Object) private Parent parent;
private Parent parent;
@JoinTypeRelations(relations = { @JoinTypeRelations(relations = {
@JoinTypeRelation(parent = "parent", children = {"child"}) @JoinTypeRelation(parent = "parent", children = { "child" })
}) }) private JoinField<String> relation = new JoinField<>("parent");
private JoinField<String> relation = new JoinField<>("parent");
private static final class Child {} private static final class Child {}
private static final class Parent {} private static final class Parent {}
public static Builder builder() { public static Builder builder() {