Skip to content

Commit dc0018e

Browse files
ls-urs-kellerukeller
authored andcommitted
Allow IndexCoordinates in repositories
It is common to have multiple indexes with the same document structure. E.g. rolling indices over time and having a wildcard alias. Sometimes one wants to select different IndexCoordinates than specified in `@Document(indexName = "...", ...)`. Also you might want to use the same Repository to do cross cluster searches and for this need to specify the IndexCoordinates. It would therefore be helpful to support IndexCoordinates as an argument to repository methods the same way ScrollPosition, Sort and Pageable are handled. This PR is an attempt to introduce this change. I keep it as draft to get some comments I can add tests to it if we can agree on the change being valid.
1 parent 8f745b1 commit dc0018e

9 files changed

+71
-10
lines changed

src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@ public Object execute(Object[] parameters) {
7979

8080
Query query = createQuery(parameters);
8181

82-
IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz);
82+
IndexCoordinates index = parameterAccessor
83+
.getIndexCoordinatesOrDefaults(elasticsearchOperations.getIndexCoordinatesFor(clazz));
8384

8485
Object result = null;
8586

8687
if (isDeleteQuery()) {
88+
index = elasticsearchOperations.getIndexCoordinatesFor(clazz);
8789
result = countOrGetDocumentsForDelete(query, parameterAccessor);
8890
elasticsearchOperations.delete(query, clazz, index);
8991
elasticsearchOperations.indexOps(index).refresh();

src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private Object execute(ElasticsearchParametersParameterAccessor parameterAccesso
9898
queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter());
9999

100100
String indexName = queryMethod.getEntityInformation().getIndexName();
101-
IndexCoordinates index = IndexCoordinates.of(indexName);
101+
IndexCoordinates index = parameterAccessor.getIndexCoordinatesOrDefaults(IndexCoordinates.of(indexName));
102102

103103
ReactiveElasticsearchQueryExecution execution = getExecution(parameterAccessor,
104104
new ResultProcessingConverter(processor));

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameter.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.elasticsearch.repository.query;
1717

1818
import org.springframework.core.MethodParameter;
19+
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
1920
import org.springframework.data.elasticsearch.core.query.RuntimeField;
2021
import org.springframework.data.elasticsearch.core.query.ScriptedField;
2122
import org.springframework.data.repository.query.Parameter;
@@ -42,7 +43,8 @@ class ElasticsearchParameter extends Parameter {
4243

4344
@Override
4445
public boolean isSpecialParameter() {
45-
return super.isSpecialParameter() || isScriptedFieldParameter() || isRuntimeFieldParameter();
46+
return super.isSpecialParameter() || isScriptedFieldParameter() || isRuntimeFieldParameter()
47+
|| isIndexCoordinatesParameter();
4648
}
4749

4850
public Boolean isScriptedFieldParameter() {
@@ -52,4 +54,7 @@ public Boolean isScriptedFieldParameter() {
5254
public Boolean isRuntimeFieldParameter() {
5355
return RuntimeField.class.isAssignableFrom(getType());
5456
}
57+
public Boolean isIndexCoordinatesParameter() {
58+
return IndexCoordinates.class.isAssignableFrom(getType());
59+
}
5560
}

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java

+4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
*/
1616
package org.springframework.data.elasticsearch.repository.query;
1717

18+
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
1819
import org.springframework.data.repository.query.ParameterAccessor;
20+
import org.springframework.lang.NonNull;
1921

2022
/**
2123
* @author Christoph Strobl
@@ -29,4 +31,6 @@ public interface ElasticsearchParameterAccessor extends ParameterAccessor {
2931
* @return
3032
*/
3133
Object[] getValues();
34+
35+
IndexCoordinates getIndexCoordinatesOrDefaults(@NonNull IndexCoordinates defaults);
3236
}

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@
2929
* @since 3.2
3030
*/
3131
public class ElasticsearchParameters extends Parameters<ElasticsearchParameters, ElasticsearchParameter> {
32-
3332
private final List<ElasticsearchParameter> scriptedFields = new ArrayList<>();
3433
private final List<ElasticsearchParameter> runtimeFields = new ArrayList<>();
3534

35+
private final int indexCoordinatesIndex;
36+
3637
public ElasticsearchParameters(Method method, TypeInformation<?> domainType) {
3738

3839
super(method, parameter -> new ElasticsearchParameter(parameter, domainType));
@@ -50,17 +51,35 @@ public ElasticsearchParameters(Method method, TypeInformation<?> domainType) {
5051
runtimeFields.add(parameter);
5152
}
5253
}
54+
this.indexCoordinatesIndex = initIndexCoordinatesIndex();
55+
}
5356

57+
private int initIndexCoordinatesIndex() {
58+
int index = 0;
59+
List<Integer> foundIndices = new ArrayList<>();
60+
for (ElasticsearchParameter parameter : this) {
61+
if (parameter.isIndexCoordinatesParameter()) {
62+
foundIndices.add(index);
63+
}
64+
index++;
65+
}
66+
if (foundIndices.size() > 1) {
67+
throw new IllegalArgumentException(this + " can only contain at most one IndexCoordinates parameter.");
68+
}
69+
return foundIndices.isEmpty() ? -1 : foundIndices.get(0);
5470
}
5571

5672
private ElasticsearchParameter parameterFactory(MethodParameter methodParameter, TypeInformation<?> domainType) {
5773
return new ElasticsearchParameter(methodParameter, domainType);
5874
}
5975

76+
6077
private ElasticsearchParameters(List<ElasticsearchParameter> parameters) {
6178
super(parameters);
79+
this.indexCoordinatesIndex = initIndexCoordinatesIndex();
6280
}
6381

82+
6483
@Override
6584
protected ElasticsearchParameters createFrom(List<ElasticsearchParameter> parameters) {
6685
return new ElasticsearchParameters(parameters);
@@ -73,4 +92,12 @@ List<ElasticsearchParameter> getScriptedFields() {
7392
List<ElasticsearchParameter> getRuntimeFields() {
7493
return runtimeFields;
7594
}
95+
96+
public boolean hasIndexCoordinatesParameter() {
97+
return this.indexCoordinatesIndex != -1;
98+
}
99+
100+
public int getIndexCoordinatesIndex() {
101+
return indexCoordinatesIndex;
102+
}
76103
}

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java

+17
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@
1515
*/
1616
package org.springframework.data.elasticsearch.repository.query;
1717

18+
import java.util.Arrays;
19+
import java.util.List;
20+
21+
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
22+
import org.springframework.data.repository.query.Parameters;
1823
import org.springframework.data.repository.query.ParametersParameterAccessor;
24+
import org.springframework.lang.NonNull;
1925

2026
/**
2127
* @author Christoph Strobl
@@ -25,6 +31,7 @@ class ElasticsearchParametersParameterAccessor extends ParametersParameterAccess
2531
implements ElasticsearchParameterAccessor {
2632

2733
private final Object[] values;
34+
private final ElasticsearchParameters eleasticSearchParameters;
2835

2936
/**
3037
* Creates a new {@link ElasticsearchParametersParameterAccessor}.
@@ -36,10 +43,20 @@ class ElasticsearchParametersParameterAccessor extends ParametersParameterAccess
3643

3744
super(method.getParameters(), values);
3845
this.values = values;
46+
this.eleasticSearchParameters = method.getParameters();
3947
}
4048

4149
@Override
4250
public Object[] getValues() {
4351
return values;
4452
}
53+
54+
55+
@Override
56+
public IndexCoordinates getIndexCoordinatesOrDefaults(@NonNull IndexCoordinates defaults) {
57+
if (!eleasticSearchParameters.hasIndexCoordinatesParameter()) {
58+
return defaults;
59+
}
60+
return (IndexCoordinates) getValues()[eleasticSearchParameters.getIndexCoordinatesIndex()];
61+
}
4562
}

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java

+5
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ private String[] mapParameters(String[] source, ParameterAccessor parameterAcces
340340
return fieldNames.toArray(new String[0]);
341341
}
342342

343+
@Override
344+
public ElasticsearchParameters getParameters() {
345+
return (ElasticsearchParameters) super.getParameters();
346+
}
347+
343348
// region Copied from QueryMethod base class
344349
/*
345350
* Copied from the QueryMethod class adding support for collections of SearchHit instances. No static method here.

src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java

-5
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,6 @@ public boolean isStreamQuery() {
142142
return true;
143143
}
144144

145-
@Override
146-
public ElasticsearchParameters getParameters() {
147-
return (ElasticsearchParameters) super.getParameters();
148-
}
149-
150145
@Override
151146
protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) {
152147
return super.isAllowedGenericType(methodGenericReturnType)

src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
import java.util.Arrays;
1919
import java.util.Iterator;
20-
import java.util.Optional;
2120

2221
import org.springframework.data.domain.Pageable;
2322
import org.springframework.data.domain.ScrollPosition;
2423
import org.springframework.data.domain.Sort;
24+
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
2525
import org.springframework.data.repository.query.ParameterAccessor;
26+
import org.springframework.lang.NonNull;
2627

2728
/**
2829
* Simple {@link ParameterAccessor} that returns the given parameters unfiltered.
@@ -97,6 +98,11 @@ public Object[] getValues() {
9798
return this.values;
9899
}
99100

101+
@Override
102+
public IndexCoordinates getIndexCoordinatesOrDefaults(@NonNull IndexCoordinates defaults) {
103+
return defaults;
104+
}
105+
100106
/*
101107
* (non-Javadoc)
102108
* @see org.springframework.data.repository.query.ParameterAccessor#findDynamicProjection()

0 commit comments

Comments
 (0)