diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java index 722b7b18f..cc3a29155 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java @@ -15,12 +15,10 @@ */ package org.springframework.data.elasticsearch.repository.query; +import java.util.Collections; + import org.springframework.data.domain.PageRequest; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.SearchHitSupport; -import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.SearchHitsImpl; -import org.springframework.data.elasticsearch.core.TotalHitsRelation; +import org.springframework.data.elasticsearch.core.*; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Query; @@ -32,8 +30,6 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import java.util.Collections; - /** * AbstractElasticsearchRepositoryQuery * @@ -74,15 +70,17 @@ public QueryMethod getQueryMethod() { @Override public Object execute(Object[] parameters) { - ParametersParameterAccessor parameterAccessor = getParameterAccessor(parameters); + ElasticsearchParametersParameterAccessor parameterAccessor = getParameterAccessor(parameters); Class clazz = getResultClass(); Query query = createQuery(parameters); - IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); + IndexCoordinates index = parameterAccessor + .getIndexCoordinatesOrDefaults(elasticsearchOperations.getIndexCoordinatesFor(clazz)); Object result = null; if (isDeleteQuery()) { + index = elasticsearchOperations.getIndexCoordinatesFor(clazz); result = countOrGetDocumentsForDelete(query, parameterAccessor); elasticsearchOperations.delete(query, clazz, index); elasticsearchOperations.indexOps(index).refresh(); @@ -158,8 +156,8 @@ private Class getResultClass() { return queryMethod.getResultProcessor().getReturnedType().getDomainType(); } - private ParametersParameterAccessor getParameterAccessor(Object[] parameters) { - return new ParametersParameterAccessor(queryMethod.getParameters(), parameters); + private ElasticsearchParametersParameterAccessor getParameterAccessor(Object[] parameters) { + return new ElasticsearchParametersParameterAccessor(queryMethod, parameters); } @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index 1bd7f652c..f68acbdbb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -95,7 +95,7 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) { } String indexName = queryMethod.getEntityInformation().getIndexName(); - IndexCoordinates index = IndexCoordinates.of(indexName); + IndexCoordinates index = parameterAccessor.getIndexCoordinatesOrDefaults(IndexCoordinates.of(indexName)); ReactiveElasticsearchQueryExecution execution = getExecution(parameterAccessor, new ResultProcessingConverter(processor)); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java index 88328c0c8..3e14cd987 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java @@ -15,7 +15,9 @@ */ package org.springframework.data.elasticsearch.repository.query; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.repository.query.ParameterAccessor; +import org.springframework.lang.NonNull; /** * @author Christoph Strobl @@ -26,7 +28,9 @@ public interface ElasticsearchParameterAccessor extends ParameterAccessor { /** * Returns the raw parameter values of the underlying query method. * - * @return + * @return values. */ Object[] getValues(); + + IndexCoordinates getIndexCoordinatesOrDefaults(@NonNull IndexCoordinates defaults); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java index 78503880a..c3a21bc31 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java @@ -16,13 +16,16 @@ package org.springframework.data.elasticsearch.repository.query; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; import org.springframework.core.MethodParameter; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.repository.query.ElasticsearchParameters.ElasticsearchParameter; import org.springframework.data.geo.Distance; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; +import org.springframework.data.util.TypeInformation; /** * @author Christoph Strobl @@ -30,18 +33,31 @@ * @since 3.2 */ public class ElasticsearchParameters extends Parameters { - - public ElasticsearchParameters(Method method) { - super(method); - } + private final int indexCoordinatesIndex; private ElasticsearchParameters(List parameters) { super(parameters); + this.indexCoordinatesIndex = initIndexCoordinatesIndex(); } - @Override - protected ElasticsearchParameter createParameter(MethodParameter parameter) { - return new ElasticsearchParameter(parameter); + public ElasticsearchParameters(Method method, TypeInformation aggregateType) { + super(method, (param) -> new ElasticsearchParameter(param, aggregateType)); + this.indexCoordinatesIndex = initIndexCoordinatesIndex(); + } + + private int initIndexCoordinatesIndex() { + int index = 0; + List foundIndices = new ArrayList<>(); + for (ElasticsearchParameter parameter : this) { + if (parameter.isIndexCoordinatesParameter()) { + foundIndices.add(index); + } + index++; + } + if (foundIndices.size() > 1) { + throw new IllegalArgumentException(this + " can only contain at most one IndexCoordinates parameter."); + } + return foundIndices.isEmpty() ? -1 : foundIndices.get(0); } @Override @@ -49,21 +65,40 @@ protected ElasticsearchParameters createFrom(List parame return new ElasticsearchParameters(parameters); } + public boolean hasIndexCoordinatesParameter() { + return this.indexCoordinatesIndex != -1; + } + + public int getIndexCoordinatesIndex() { + return indexCoordinatesIndex; + } + /** * Custom {@link Parameter} implementation adding parameters of type {@link Distance} to the special ones. * * @author Christoph Strobl */ - class ElasticsearchParameter extends Parameter { + static class ElasticsearchParameter extends Parameter { + + private final boolean indexCoordinatesParameter; /** * Creates a new {@link ElasticsearchParameter}. * * @param parameter must not be {@literal null}. */ - ElasticsearchParameter(MethodParameter parameter) { - super(parameter); + ElasticsearchParameter(MethodParameter parameter, TypeInformation aggregateType) { + super(parameter, aggregateType); + this.indexCoordinatesParameter = parameter.getParameter().getType().isAssignableFrom(IndexCoordinates.class); } + @Override + public boolean isSpecialParameter() { + return isIndexCoordinatesParameter() || super.isSpecialParameter(); + } + + public boolean isIndexCoordinatesParameter() { + return this.indexCoordinatesParameter; + } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java index d7107c51a..4053b73f6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java @@ -18,7 +18,9 @@ import java.util.Arrays; import java.util.List; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.repository.query.ParametersParameterAccessor; +import org.springframework.lang.NonNull; /** * @author Christoph Strobl @@ -36,13 +38,25 @@ class ElasticsearchParametersParameterAccessor extends ParametersParameterAccess * @param values must not be {@literal null}. */ ElasticsearchParametersParameterAccessor(ElasticsearchQueryMethod method, Object... values) { - super(method.getParameters(), values); this.values = Arrays.asList(values); } + @Override + public ElasticsearchParameters getParameters() { + return (ElasticsearchParameters) super.getParameters(); + } + @Override public Object[] getValues() { return values.toArray(); } + + @Override + public IndexCoordinates getIndexCoordinatesOrDefaults(@NonNull IndexCoordinates defaults) { + if (!getParameters().hasIndexCoordinatesParameter()) { + return defaults; + } + return (IndexCoordinates) getValues()[getParameters().getIndexCoordinatesIndex()]; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java index bad23c8a7..d0b2ce473 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java @@ -322,4 +322,14 @@ private String[] mapParameters(String[] source, ParameterAccessor parameterAcces return fieldNames.toArray(new String[0]); } + + @Override + protected ElasticsearchParameters createParameters(Method method, TypeInformation domainType) { + return new ElasticsearchParameters(method, domainType); + } + + @Override + public ElasticsearchParameters getParameters() { + return (ElasticsearchParameters) super.getParameters(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java index d43073dc1..bba53bee3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java @@ -81,7 +81,7 @@ protected T getValue(int index) { @Override public Object[] getValues() { - Object[] result = new Object[getValues().length]; + Object[] result = new Object[super.getValues().length]; for (int i = 0; i < result.length; i++) { result[i] = getValue(i); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java index 1c03d0b14..5ac93d87c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java @@ -15,7 +15,7 @@ */ package org.springframework.data.elasticsearch.repository.query; -import static org.springframework.data.repository.util.ClassUtils.*; +import static org.springframework.data.repository.util.ClassUtils.hasParameterOfType; import reactor.core.publisher.Mono; @@ -102,11 +102,6 @@ protected void verifyCountQueryTypes() { } } - @Override - protected ElasticsearchParameters createParameters(Method method) { - return new ElasticsearchParameters(method); - } - /** * Check if the given {@link org.springframework.data.repository.query.QueryMethod} receives a reactive parameter * wrapper as one of its parameters. @@ -143,11 +138,6 @@ public boolean isStreamQuery() { return true; } - @Override - public ElasticsearchParameters getParameters() { - return (ElasticsearchParameters) super.getParameters(); - } - @Override protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) { return super.isAllowedGenericType(methodGenericReturnType) diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java index 69c35f0c1..d4c5374cf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java @@ -17,12 +17,13 @@ import java.util.Arrays; import java.util.Iterator; -import java.util.Optional; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.ScrollPosition; import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.repository.query.ParameterAccessor; +import org.springframework.lang.NonNull; /** * Simple {@link ParameterAccessor} that returns the given parameters unfiltered. @@ -97,6 +98,11 @@ public Object[] getValues() { return this.values; } + @Override + public IndexCoordinates getIndexCoordinatesOrDefaults(@NonNull IndexCoordinates defaults) { + return defaults; + } + /* * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#findDynamicProjection()