Skip to content

Commit 26e7538

Browse files
committed
Allow index names per query in bulk requests.
Closes spring-projects#2043
1 parent 266dd57 commit 26e7538

File tree

8 files changed

+126
-23
lines changed

8 files changed

+126
-23
lines changed

Diff for: src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ private List<MultiGetRequest.Item> getMultiRequestItems(Query searchQuery, Class
600600
// region indexing
601601
public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) {
602602

603-
String indexName = index.getIndexName();
603+
String indexName = query.getIndexName() != null ? query.getIndexName() : index.getIndexName();
604604
IndexRequest indexRequest;
605605

606606
Object queryObject = query.getObject();
@@ -1027,7 +1027,7 @@ private QueryRescorerBuilder getQueryRescorerBuilder(RescorerQuery rescorerQuery
10271027
// region update
10281028
public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) {
10291029

1030-
String indexName = index.getIndexName();
1030+
String indexName = query.getIndexName() != null ? query.getIndexName() : index.getIndexName();
10311031
UpdateRequest updateRequest = new UpdateRequest(indexName, query.getId());
10321032

10331033
if (query.getScript() != null) {

Diff for: src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ public class IndexQuery {
3838
@Nullable private Long primaryTerm;
3939
@Nullable private String routing;
4040
@Nullable private OpType opType;
41+
@Nullable private String indexName;
4142

4243
public IndexQuery() {}
4344

4445
public IndexQuery(@Nullable String id, @Nullable Object object, @Nullable Long version, @Nullable String source,
4546
@Nullable String parentId, @Nullable Long seqNo, @Nullable Long primaryTerm, @Nullable String routing,
46-
@Nullable OpType opType) {
47+
@Nullable OpType opType, @Nullable String indexName) {
4748
this.id = id;
4849
this.object = object;
4950
this.version = version;
@@ -53,6 +54,7 @@ public IndexQuery(@Nullable String id, @Nullable Object object, @Nullable Long v
5354
this.primaryTerm = primaryTerm;
5455
this.routing = routing;
5556
this.opType = opType;
57+
this.indexName = indexName;
5658
}
5759

5860
@Nullable
@@ -152,6 +154,14 @@ public void setOpType(OpType opType) {
152154
this.opType = opType;
153155
}
154156

157+
/**
158+
* @since 4.4
159+
*/
160+
@Nullable
161+
public String getIndexName() {
162+
return indexName;
163+
}
164+
155165
/**
156166
* OpType for the index operation.
157167
*

Diff for: src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class IndexQueryBuilder {
4040
@Nullable private String routing;
4141
@Nullable private IndexQuery.OpType opType;
4242
@Nullable private RefreshPolicy refreshPolicy;
43+
@Nullable private String indexName;
4344

4445
public IndexQueryBuilder() {}
4546

@@ -89,6 +90,14 @@ public IndexQueryBuilder withOpType(IndexQuery.OpType opType) {
8990
}
9091

9192
public IndexQuery build() {
92-
return new IndexQuery(id, object, version, source, parentId, seqNo, primaryTerm, routing, opType);
93+
return new IndexQuery(id, object, version, source, parentId, seqNo, primaryTerm, routing, opType, indexName);
94+
}
95+
96+
/**
97+
* @since 4.4
98+
*/
99+
public IndexQueryBuilder withIndex(@Nullable String indexName) {
100+
this.indexName = indexName;
101+
return this;
93102
}
94103
}

Diff for: src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public class UpdateQuery {
6363
@Nullable private final Integer slices;
6464
@Nullable private final ScriptType scriptType;
6565
@Nullable private final String scriptName;
66+
@Nullable private final String indexName;
6667

6768
public static Builder builder(String id) {
6869
return new Builder(id);
@@ -81,7 +82,7 @@ private UpdateQuery(String id, @Nullable String script, @Nullable Map<String, Ob
8182
@Nullable Boolean abortOnVersionConflict, @Nullable Integer batchSize, @Nullable Integer maxDocs,
8283
@Nullable Integer maxRetries, @Nullable String pipeline, @Nullable Float requestsPerSecond,
8384
@Nullable Boolean shouldStoreResult, @Nullable Integer slices, @Nullable ScriptType scriptType,
84-
@Nullable String scriptName) {
85+
@Nullable String scriptName, @Nullable String indexName) {
8586

8687
this.id = id;
8788
this.script = script;
@@ -112,6 +113,7 @@ private UpdateQuery(String id, @Nullable String script, @Nullable Map<String, Ob
112113
this.slices = slices;
113114
this.scriptType = scriptType;
114115
this.scriptName = scriptName;
116+
this.indexName = indexName;
115117
}
116118

117119
public String getId() {
@@ -258,6 +260,14 @@ public String getScriptName() {
258260
return scriptName;
259261
}
260262

263+
/**
264+
* @since 4.4
265+
*/
266+
@Nullable
267+
public String getIndexName() {
268+
return indexName;
269+
}
270+
261271
public static final class Builder {
262272
private String id;
263273
@Nullable private String script = null;
@@ -288,6 +298,7 @@ public static final class Builder {
288298
@Nullable private Integer slices;
289299
@Nullable private ScriptType scriptType;
290300
@Nullable private String scriptName;
301+
@Nullable private String indexName;
291302

292303
private Builder(String id) {
293304
this.id = id;
@@ -441,7 +452,12 @@ public UpdateQuery build() {
441452
return new UpdateQuery(id, script, params, document, upsert, lang, routing, scriptedUpsert, docAsUpsert,
442453
fetchSource, fetchSourceIncludes, fetchSourceExcludes, ifSeqNo, ifPrimaryTerm, refreshPolicy, retryOnConflict,
443454
timeout, waitForActiveShards, query, abortOnVersionConflict, batchSize, maxDocs, maxRetries, pipeline,
444-
requestsPerSecond, shouldStoreResult, slices, scriptType, scriptName);
455+
requestsPerSecond, shouldStoreResult, slices, scriptType, scriptName, indexName);
456+
}
457+
458+
public Builder withIndex(@Nullable String indexName) {
459+
this.indexName = indexName;
460+
return this;
445461
}
446462
}
447463
}

Diff for: src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java

+80-14
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
3030
import org.elasticsearch.action.index.IndexRequest;
3131
import org.elasticsearch.action.search.SearchRequest;
32+
import org.elasticsearch.action.update.UpdateRequest;
3233
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
3334
import org.elasticsearch.common.lucene.search.function.CombineFunction;
3435
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
@@ -57,12 +58,12 @@
5758
import org.springframework.data.elasticsearch.core.index.AliasActionParameters;
5859
import org.springframework.data.elasticsearch.core.index.AliasActions;
5960
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
60-
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
61-
import org.springframework.data.elasticsearch.core.reindex.Remote;
6261
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
6362
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
6463
import org.springframework.data.elasticsearch.core.query.*;
6564
import org.springframework.data.elasticsearch.core.query.RescorerQuery.ScoreMode;
65+
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
66+
import org.springframework.data.elasticsearch.core.reindex.Remote;
6667
import org.springframework.lang.Nullable;
6768

6869
/**
@@ -92,7 +93,8 @@ static void setUpAll() {
9293
requestFactory = new RequestFactory((converter));
9394
}
9495

95-
@Test // FPI-734
96+
@Test
97+
// FPI-734
9698
void shouldBuildSearchWithGeoSortSort() throws JSONException {
9799
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
98100
Sort sort = Sort.by(new GeoDistanceOrder("location", new GeoPoint(49.0, 8.4)));
@@ -140,7 +142,8 @@ void shouldBuildSearchWithGeoSortSort() throws JSONException {
140142
assertEquals(expected, searchRequest, false);
141143
}
142144

143-
@Test // DATAES-449
145+
@Test
146+
// DATAES-449
144147
void shouldAddRouting() {
145148
String route = "route66";
146149
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
@@ -152,7 +155,8 @@ void shouldAddRouting() {
152155
assertThat(searchRequest.routing()).isEqualTo(route);
153156
}
154157

155-
@Test // DATAES-765
158+
@Test
159+
// DATAES-765
156160
void shouldAddMaxQueryWindowForUnpagedToRequest() {
157161
Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(Pageable.unpaged()).build();
158162

@@ -162,7 +166,8 @@ void shouldAddMaxQueryWindowForUnpagedToRequest() {
162166
assertThat(searchRequest.source().size()).isEqualTo(RequestFactory.INDEX_MAX_RESULT_WINDOW);
163167
}
164168

165-
@Test // DATAES-799
169+
@Test
170+
// DATAES-799
166171
void shouldIncludeSeqNoAndPrimaryTermFromIndexQueryToIndexRequest() {
167172
IndexQuery query = new IndexQuery();
168173
query.setObject(new Person());
@@ -175,7 +180,8 @@ void shouldIncludeSeqNoAndPrimaryTermFromIndexQueryToIndexRequest() {
175180
assertThat(request.ifPrimaryTerm()).isEqualTo(2L);
176181
}
177182

178-
@Test // DATAES-799
183+
@Test
184+
// DATAES-799
179185
void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassDoesNotContainSeqNoPrimaryTermProperty() {
180186
Query query = new NativeSearchQueryBuilder().build();
181187

@@ -184,7 +190,8 @@ void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassDoesNotContainSeqNoPrimar
184190
assertThat(request.source().seqNoAndPrimaryTerm()).isNull();
185191
}
186192

187-
@Test // DATAES-799
193+
@Test
194+
// DATAES-799
188195
void shouldRequestSeqNoAndPrimaryTermWhenEntityClassContainsSeqNoPrimaryTermProperty() {
189196
Query query = new NativeSearchQueryBuilder().build();
190197

@@ -194,7 +201,8 @@ void shouldRequestSeqNoAndPrimaryTermWhenEntityClassContainsSeqNoPrimaryTermProp
194201
assertThat(request.source().seqNoAndPrimaryTerm()).isTrue();
195202
}
196203

197-
@Test // DATAES-799
204+
@Test
205+
// DATAES-799
198206
void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassIsNull() {
199207
Query query = new NativeSearchQueryBuilder().build();
200208

@@ -203,7 +211,8 @@ void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassIsNull() {
203211
assertThat(request.source().seqNoAndPrimaryTerm()).isNull();
204212
}
205213

206-
@Test // DATAES-864
214+
@Test
215+
// DATAES-864
207216
void shouldBuildIndicesAliasRequest() throws IOException, JSONException {
208217

209218
AliasActions aliasActions = new AliasActions();
@@ -316,7 +325,8 @@ void shouldBuildIndicesAliasRequest() throws IOException, JSONException {
316325
assertEquals(expected, json, false);
317326
}
318327

319-
@Test // DATAES-612
328+
@Test
329+
// DATAES-612
320330
void shouldCreatePutIndexTemplateRequest() throws JSONException, IOException {
321331

322332
String expected = "{\n" + //
@@ -430,7 +440,8 @@ private String requestToString(ToXContent request) throws IOException {
430440
return XContentHelper.toXContent(request, XContentType.JSON, true).utf8ToString();
431441
}
432442

433-
@Test // #1686
443+
@Test
444+
// #1686
434445
void shouldBuildSearchWithRescorerQuery() throws JSONException {
435446
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
436447
RescorerQuery rescorerQuery = new RescorerQuery(new NativeSearchQueryBuilder() //
@@ -546,7 +557,7 @@ void shouldSetRequestCacheFalseOnSearchRequest() {
546557
assertThat(searchRequest.requestCache()).isFalse();
547558
}
548559

549-
@Test
560+
@Test // #2004
550561
@DisplayName("should set stored fields on SearchRequest")
551562
void shouldSetStoredFieldsOnSearchRequest() {
552563

@@ -560,7 +571,8 @@ void shouldSetStoredFieldsOnSearchRequest() {
560571
.isEqualTo(Arrays.asList("last-name", "current-location"));
561572
}
562573

563-
@Test // #1529
574+
@Test
575+
// #1529
564576
void shouldCreateReindexRequest() throws IOException, JSONException {
565577
final String expected = "{\n" + //
566578
" \"source\":{\n" + //
@@ -608,6 +620,7 @@ void shouldCreateReindexRequest() throws IOException, JSONException {
608620
}
609621

610622
@Test
623+
// #1529
611624
void shouldAllowSourceQueryForReindexWithoutRemote() throws IOException, JSONException {
612625
final String expected = "{\n" + //
613626
" \"source\":{\n" + //
@@ -644,6 +657,59 @@ void shouldNotFailOnEmptyWildcardStatesOnToElasticsearchIndicesOptions() {
644657
.isNotNull();
645658
}
646659

660+
@Test // #2043
661+
@DisplayName("should use index name from query if set in bulk index")
662+
void shouldUseIndexNameFromQueryIfSetInBulkIndex() {
663+
664+
String queryIndexName = "query-index-name";
665+
String methodIndexName = "method-index-name";
666+
IndexQuery indexQuery = new IndexQueryBuilder().withIndex(queryIndexName).withId("42").withObject(new Person())
667+
.build();
668+
669+
IndexRequest indexRequest = requestFactory.indexRequest(indexQuery, IndexCoordinates.of(methodIndexName));
670+
671+
assertThat(indexRequest.index()).isEqualTo(queryIndexName);
672+
}
673+
674+
@Test // #2043
675+
@DisplayName("should use index name from method if none is set in query in bulk index")
676+
void shouldUseIndexNameFromMethodIfNoneIsSetInQueryInBulkIndex() {
677+
678+
String methodIndexName = "method-index-name";
679+
IndexQuery indexQuery = new IndexQueryBuilder().withId("42").withObject(new Person()).build();
680+
681+
IndexRequest indexRequest = requestFactory.indexRequest(indexQuery, IndexCoordinates.of(methodIndexName));
682+
683+
assertThat(indexRequest.index()).isEqualTo(methodIndexName);
684+
}
685+
686+
@Test // #2043
687+
@DisplayName("should use index name from query if set in bulk update")
688+
void shouldUseIndexNameFromQueryIfSetInBulkUpdate() {
689+
690+
String queryIndexName = "query-index-name";
691+
String methodIndexName = "method-index-name";
692+
UpdateQuery updateQuery = UpdateQuery.builder("42").withIndex(queryIndexName)
693+
.withDocument(org.springframework.data.elasticsearch.core.document.Document.create()).build();
694+
695+
UpdateRequest updateRequest = requestFactory.updateRequest(updateQuery, IndexCoordinates.of(methodIndexName));
696+
697+
assertThat(updateRequest.index()).isEqualTo(queryIndexName);
698+
}
699+
700+
@Test // #2043
701+
@DisplayName("should use index name from method if none is set in query in bulk update")
702+
void shouldUseIndexNameFromMethodIfNoneIsSetInQueryInBulkUpdate() {
703+
704+
String methodIndexName = "method-index-name";
705+
UpdateQuery updateQuery = UpdateQuery.builder("42")
706+
.withDocument(org.springframework.data.elasticsearch.core.document.Document.create()).build();
707+
708+
UpdateRequest updateRequest = requestFactory.updateRequest(updateQuery, IndexCoordinates.of(methodIndexName));
709+
710+
assertThat(updateRequest.index()).isEqualTo(methodIndexName);
711+
}
712+
647713
// region entities
648714
static class Person {
649715
@Nullable

Diff for: src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryRestTemplateIntegrationTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class CriteriaQueryRestTemplateIntegrationTests extends CriteriaQueryInte
3333
static class Config {
3434
@Bean
3535
IndexNameProvider indexNameProvider() {
36-
return new IndexNameProvider();
36+
return new IndexNameProvider("criteria-query-es7");
3737
}
3838
}
3939

Diff for: src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryRestTemplateIntegrationTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@
2828
*/
2929
@ContextConfiguration(classes = { DoubleIDRepositoryRestTemplateIntegrationTests.Config.class })
3030
public class DoubleIDRepositoryRestTemplateIntegrationTests extends DoubleIDRepositoryIntegrationTests {
31+
3132
@Configuration
3233
@Import({ ElasticsearchRestTemplateConfiguration.class })
3334
@EnableElasticsearchRepositories(considerNestedRepositories = true)
3435
static class Config {
3536
@Bean
3637
IndexNameProvider indexNameProvider() {
37-
return new IndexNameProvider();
38+
return new IndexNameProvider("doubleid-reository-es7");
3839
}
3940
}
4041
}

Diff for: src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@
2929
@ContextConfiguration(classes = { DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests.Config.class })
3030
public class DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests
3131
extends DynamicSettingAndMappingEntityRepositoryIntegrationTests {
32+
3233
@Configuration
3334
@Import({ ElasticsearchRestTemplateConfiguration.class })
3435
@EnableElasticsearchRepositories(considerNestedRepositories = true)
3536
static class Config {
3637
@Bean
3738
IndexNameProvider indexNameProvider() {
38-
return new IndexNameProvider();
39+
return new IndexNameProvider("dynamic-setting-and-mapping-3s7");
3940
}
4041
}
4142

0 commit comments

Comments
 (0)