Allow index names per query in bulk requests.

Original Pull Request #2079
Closes #2043
This commit is contained in:
Peter-Josef Meisch 2022-02-06 11:35:32 +01:00 committed by GitHub
parent 266dd573ae
commit e54c03d06a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 126 additions and 23 deletions

View File

@ -600,7 +600,7 @@ class RequestFactory {
// region indexing // region indexing
public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) {
String indexName = index.getIndexName(); String indexName = query.getIndexName() != null ? query.getIndexName() : index.getIndexName();
IndexRequest indexRequest; IndexRequest indexRequest;
Object queryObject = query.getObject(); Object queryObject = query.getObject();
@ -1027,7 +1027,7 @@ class RequestFactory {
// region update // region update
public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) {
String indexName = index.getIndexName(); String indexName = query.getIndexName() != null ? query.getIndexName() : index.getIndexName();
UpdateRequest updateRequest = new UpdateRequest(indexName, query.getId()); UpdateRequest updateRequest = new UpdateRequest(indexName, query.getId());
if (query.getScript() != null) { if (query.getScript() != null) {

View File

@ -38,12 +38,13 @@ public class IndexQuery {
@Nullable private Long primaryTerm; @Nullable private Long primaryTerm;
@Nullable private String routing; @Nullable private String routing;
@Nullable private OpType opType; @Nullable private OpType opType;
@Nullable private String indexName;
public IndexQuery() {} public IndexQuery() {}
public IndexQuery(@Nullable String id, @Nullable Object object, @Nullable Long version, @Nullable String source, public IndexQuery(@Nullable String id, @Nullable Object object, @Nullable Long version, @Nullable String source,
@Nullable String parentId, @Nullable Long seqNo, @Nullable Long primaryTerm, @Nullable String routing, @Nullable String parentId, @Nullable Long seqNo, @Nullable Long primaryTerm, @Nullable String routing,
@Nullable OpType opType) { @Nullable OpType opType, @Nullable String indexName) {
this.id = id; this.id = id;
this.object = object; this.object = object;
this.version = version; this.version = version;
@ -53,6 +54,7 @@ public class IndexQuery {
this.primaryTerm = primaryTerm; this.primaryTerm = primaryTerm;
this.routing = routing; this.routing = routing;
this.opType = opType; this.opType = opType;
this.indexName = indexName;
} }
@Nullable @Nullable
@ -152,6 +154,14 @@ public class IndexQuery {
this.opType = opType; this.opType = opType;
} }
/**
* @since 4.4
*/
@Nullable
public String getIndexName() {
return indexName;
}
/** /**
* OpType for the index operation. * OpType for the index operation.
* *

View File

@ -40,6 +40,7 @@ public class IndexQueryBuilder {
@Nullable private String routing; @Nullable private String routing;
@Nullable private IndexQuery.OpType opType; @Nullable private IndexQuery.OpType opType;
@Nullable private RefreshPolicy refreshPolicy; @Nullable private RefreshPolicy refreshPolicy;
@Nullable private String indexName;
public IndexQueryBuilder() {} public IndexQueryBuilder() {}
@ -89,6 +90,14 @@ public class IndexQueryBuilder {
} }
public IndexQuery build() { public IndexQuery build() {
return new IndexQuery(id, object, version, source, parentId, seqNo, primaryTerm, routing, opType); return new IndexQuery(id, object, version, source, parentId, seqNo, primaryTerm, routing, opType, indexName);
}
/**
* @since 4.4
*/
public IndexQueryBuilder withIndex(@Nullable String indexName) {
this.indexName = indexName;
return this;
} }
} }

View File

@ -63,6 +63,7 @@ public class UpdateQuery {
@Nullable private final Integer slices; @Nullable private final Integer slices;
@Nullable private final ScriptType scriptType; @Nullable private final ScriptType scriptType;
@Nullable private final String scriptName; @Nullable private final String scriptName;
@Nullable private final String indexName;
public static Builder builder(String id) { public static Builder builder(String id) {
return new Builder(id); return new Builder(id);
@ -81,7 +82,7 @@ public class UpdateQuery {
@Nullable Boolean abortOnVersionConflict, @Nullable Integer batchSize, @Nullable Integer maxDocs, @Nullable Boolean abortOnVersionConflict, @Nullable Integer batchSize, @Nullable Integer maxDocs,
@Nullable Integer maxRetries, @Nullable String pipeline, @Nullable Float requestsPerSecond, @Nullable Integer maxRetries, @Nullable String pipeline, @Nullable Float requestsPerSecond,
@Nullable Boolean shouldStoreResult, @Nullable Integer slices, @Nullable ScriptType scriptType, @Nullable Boolean shouldStoreResult, @Nullable Integer slices, @Nullable ScriptType scriptType,
@Nullable String scriptName) { @Nullable String scriptName, @Nullable String indexName) {
this.id = id; this.id = id;
this.script = script; this.script = script;
@ -112,6 +113,7 @@ public class UpdateQuery {
this.slices = slices; this.slices = slices;
this.scriptType = scriptType; this.scriptType = scriptType;
this.scriptName = scriptName; this.scriptName = scriptName;
this.indexName = indexName;
} }
public String getId() { public String getId() {
@ -258,6 +260,14 @@ public class UpdateQuery {
return scriptName; return scriptName;
} }
/**
* @since 4.4
*/
@Nullable
public String getIndexName() {
return indexName;
}
public static final class Builder { public static final class Builder {
private String id; private String id;
@Nullable private String script = null; @Nullable private String script = null;
@ -288,6 +298,7 @@ public class UpdateQuery {
@Nullable private Integer slices; @Nullable private Integer slices;
@Nullable private ScriptType scriptType; @Nullable private ScriptType scriptType;
@Nullable private String scriptName; @Nullable private String scriptName;
@Nullable private String indexName;
private Builder(String id) { private Builder(String id) {
this.id = id; this.id = id;
@ -441,7 +452,12 @@ public class UpdateQuery {
return new UpdateQuery(id, script, params, document, upsert, lang, routing, scriptedUpsert, docAsUpsert, return new UpdateQuery(id, script, params, document, upsert, lang, routing, scriptedUpsert, docAsUpsert,
fetchSource, fetchSourceIncludes, fetchSourceExcludes, ifSeqNo, ifPrimaryTerm, refreshPolicy, retryOnConflict, fetchSource, fetchSourceIncludes, fetchSourceExcludes, ifSeqNo, ifPrimaryTerm, refreshPolicy, retryOnConflict,
timeout, waitForActiveShards, query, abortOnVersionConflict, batchSize, maxDocs, maxRetries, pipeline, timeout, waitForActiveShards, query, abortOnVersionConflict, batchSize, maxDocs, maxRetries, pipeline,
requestsPerSecond, shouldStoreResult, slices, scriptType, scriptName); requestsPerSecond, shouldStoreResult, slices, scriptType, scriptName, indexName);
}
public Builder withIndex(@Nullable String indexName) {
this.indexName = indexName;
return this;
} }
} }
} }

View File

@ -29,6 +29,7 @@ import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.client.indices.PutIndexTemplateRequest;
import org.elasticsearch.common.lucene.search.function.CombineFunction; import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery; import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
@ -57,12 +58,12 @@ import org.springframework.data.elasticsearch.core.index.AliasAction;
import org.springframework.data.elasticsearch.core.index.AliasActionParameters; import org.springframework.data.elasticsearch.core.index.AliasActionParameters;
import org.springframework.data.elasticsearch.core.index.AliasActions; import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest; import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
import org.springframework.data.elasticsearch.core.reindex.Remote;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.core.query.RescorerQuery.ScoreMode; import org.springframework.data.elasticsearch.core.query.RescorerQuery.ScoreMode;
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
import org.springframework.data.elasticsearch.core.reindex.Remote;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
@ -92,7 +93,8 @@ class RequestFactoryTests {
requestFactory = new RequestFactory((converter)); requestFactory = new RequestFactory((converter));
} }
@Test // FPI-734 @Test
// FPI-734
void shouldBuildSearchWithGeoSortSort() throws JSONException { void shouldBuildSearchWithGeoSortSort() throws JSONException {
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith")); CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
Sort sort = Sort.by(new GeoDistanceOrder("location", new GeoPoint(49.0, 8.4))); Sort sort = Sort.by(new GeoDistanceOrder("location", new GeoPoint(49.0, 8.4)));
@ -140,7 +142,8 @@ class RequestFactoryTests {
assertEquals(expected, searchRequest, false); assertEquals(expected, searchRequest, false);
} }
@Test // DATAES-449 @Test
// DATAES-449
void shouldAddRouting() { void shouldAddRouting() {
String route = "route66"; String route = "route66";
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith")); CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
@ -152,7 +155,8 @@ class RequestFactoryTests {
assertThat(searchRequest.routing()).isEqualTo(route); assertThat(searchRequest.routing()).isEqualTo(route);
} }
@Test // DATAES-765 @Test
// DATAES-765
void shouldAddMaxQueryWindowForUnpagedToRequest() { void shouldAddMaxQueryWindowForUnpagedToRequest() {
Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(Pageable.unpaged()).build(); Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(Pageable.unpaged()).build();
@ -162,7 +166,8 @@ class RequestFactoryTests {
assertThat(searchRequest.source().size()).isEqualTo(RequestFactory.INDEX_MAX_RESULT_WINDOW); assertThat(searchRequest.source().size()).isEqualTo(RequestFactory.INDEX_MAX_RESULT_WINDOW);
} }
@Test // DATAES-799 @Test
// DATAES-799
void shouldIncludeSeqNoAndPrimaryTermFromIndexQueryToIndexRequest() { void shouldIncludeSeqNoAndPrimaryTermFromIndexQueryToIndexRequest() {
IndexQuery query = new IndexQuery(); IndexQuery query = new IndexQuery();
query.setObject(new Person()); query.setObject(new Person());
@ -175,7 +180,8 @@ class RequestFactoryTests {
assertThat(request.ifPrimaryTerm()).isEqualTo(2L); assertThat(request.ifPrimaryTerm()).isEqualTo(2L);
} }
@Test // DATAES-799 @Test
// DATAES-799
void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassDoesNotContainSeqNoPrimaryTermProperty() { void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassDoesNotContainSeqNoPrimaryTermProperty() {
Query query = new NativeSearchQueryBuilder().build(); Query query = new NativeSearchQueryBuilder().build();
@ -184,7 +190,8 @@ class RequestFactoryTests {
assertThat(request.source().seqNoAndPrimaryTerm()).isNull(); assertThat(request.source().seqNoAndPrimaryTerm()).isNull();
} }
@Test // DATAES-799 @Test
// DATAES-799
void shouldRequestSeqNoAndPrimaryTermWhenEntityClassContainsSeqNoPrimaryTermProperty() { void shouldRequestSeqNoAndPrimaryTermWhenEntityClassContainsSeqNoPrimaryTermProperty() {
Query query = new NativeSearchQueryBuilder().build(); Query query = new NativeSearchQueryBuilder().build();
@ -194,7 +201,8 @@ class RequestFactoryTests {
assertThat(request.source().seqNoAndPrimaryTerm()).isTrue(); assertThat(request.source().seqNoAndPrimaryTerm()).isTrue();
} }
@Test // DATAES-799 @Test
// DATAES-799
void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassIsNull() { void shouldNotRequestSeqNoAndPrimaryTermWhenEntityClassIsNull() {
Query query = new NativeSearchQueryBuilder().build(); Query query = new NativeSearchQueryBuilder().build();
@ -203,7 +211,8 @@ class RequestFactoryTests {
assertThat(request.source().seqNoAndPrimaryTerm()).isNull(); assertThat(request.source().seqNoAndPrimaryTerm()).isNull();
} }
@Test // DATAES-864 @Test
// DATAES-864
void shouldBuildIndicesAliasRequest() throws IOException, JSONException { void shouldBuildIndicesAliasRequest() throws IOException, JSONException {
AliasActions aliasActions = new AliasActions(); AliasActions aliasActions = new AliasActions();
@ -316,7 +325,8 @@ class RequestFactoryTests {
assertEquals(expected, json, false); assertEquals(expected, json, false);
} }
@Test // DATAES-612 @Test
// DATAES-612
void shouldCreatePutIndexTemplateRequest() throws JSONException, IOException { void shouldCreatePutIndexTemplateRequest() throws JSONException, IOException {
String expected = "{\n" + // String expected = "{\n" + //
@ -430,7 +440,8 @@ class RequestFactoryTests {
return XContentHelper.toXContent(request, XContentType.JSON, true).utf8ToString(); return XContentHelper.toXContent(request, XContentType.JSON, true).utf8ToString();
} }
@Test // #1686 @Test
// #1686
void shouldBuildSearchWithRescorerQuery() throws JSONException { void shouldBuildSearchWithRescorerQuery() throws JSONException {
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith")); CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
RescorerQuery rescorerQuery = new RescorerQuery(new NativeSearchQueryBuilder() // RescorerQuery rescorerQuery = new RescorerQuery(new NativeSearchQueryBuilder() //
@ -546,7 +557,7 @@ class RequestFactoryTests {
assertThat(searchRequest.requestCache()).isFalse(); assertThat(searchRequest.requestCache()).isFalse();
} }
@Test @Test // #2004
@DisplayName("should set stored fields on SearchRequest") @DisplayName("should set stored fields on SearchRequest")
void shouldSetStoredFieldsOnSearchRequest() { void shouldSetStoredFieldsOnSearchRequest() {
@ -560,7 +571,8 @@ class RequestFactoryTests {
.isEqualTo(Arrays.asList("last-name", "current-location")); .isEqualTo(Arrays.asList("last-name", "current-location"));
} }
@Test // #1529 @Test
// #1529
void shouldCreateReindexRequest() throws IOException, JSONException { void shouldCreateReindexRequest() throws IOException, JSONException {
final String expected = "{\n" + // final String expected = "{\n" + //
" \"source\":{\n" + // " \"source\":{\n" + //
@ -608,6 +620,7 @@ class RequestFactoryTests {
} }
@Test @Test
// #1529
void shouldAllowSourceQueryForReindexWithoutRemote() throws IOException, JSONException { void shouldAllowSourceQueryForReindexWithoutRemote() throws IOException, JSONException {
final String expected = "{\n" + // final String expected = "{\n" + //
" \"source\":{\n" + // " \"source\":{\n" + //
@ -644,6 +657,59 @@ class RequestFactoryTests {
.isNotNull(); .isNotNull();
} }
@Test // #2043
@DisplayName("should use index name from query if set in bulk index")
void shouldUseIndexNameFromQueryIfSetInBulkIndex() {
String queryIndexName = "query-index-name";
String methodIndexName = "method-index-name";
IndexQuery indexQuery = new IndexQueryBuilder().withIndex(queryIndexName).withId("42").withObject(new Person())
.build();
IndexRequest indexRequest = requestFactory.indexRequest(indexQuery, IndexCoordinates.of(methodIndexName));
assertThat(indexRequest.index()).isEqualTo(queryIndexName);
}
@Test // #2043
@DisplayName("should use index name from method if none is set in query in bulk index")
void shouldUseIndexNameFromMethodIfNoneIsSetInQueryInBulkIndex() {
String methodIndexName = "method-index-name";
IndexQuery indexQuery = new IndexQueryBuilder().withId("42").withObject(new Person()).build();
IndexRequest indexRequest = requestFactory.indexRequest(indexQuery, IndexCoordinates.of(methodIndexName));
assertThat(indexRequest.index()).isEqualTo(methodIndexName);
}
@Test // #2043
@DisplayName("should use index name from query if set in bulk update")
void shouldUseIndexNameFromQueryIfSetInBulkUpdate() {
String queryIndexName = "query-index-name";
String methodIndexName = "method-index-name";
UpdateQuery updateQuery = UpdateQuery.builder("42").withIndex(queryIndexName)
.withDocument(org.springframework.data.elasticsearch.core.document.Document.create()).build();
UpdateRequest updateRequest = requestFactory.updateRequest(updateQuery, IndexCoordinates.of(methodIndexName));
assertThat(updateRequest.index()).isEqualTo(queryIndexName);
}
@Test // #2043
@DisplayName("should use index name from method if none is set in query in bulk update")
void shouldUseIndexNameFromMethodIfNoneIsSetInQueryInBulkUpdate() {
String methodIndexName = "method-index-name";
UpdateQuery updateQuery = UpdateQuery.builder("42")
.withDocument(org.springframework.data.elasticsearch.core.document.Document.create()).build();
UpdateRequest updateRequest = requestFactory.updateRequest(updateQuery, IndexCoordinates.of(methodIndexName));
assertThat(updateRequest.index()).isEqualTo(methodIndexName);
}
// region entities // region entities
static class Person { static class Person {
@Nullable @Nullable

View File

@ -33,7 +33,7 @@ public class CriteriaQueryRestTemplateIntegrationTests extends CriteriaQueryInte
static class Config { static class Config {
@Bean @Bean
IndexNameProvider indexNameProvider() { IndexNameProvider indexNameProvider() {
return new IndexNameProvider(); return new IndexNameProvider("criteria-query-es7");
} }
} }

View File

@ -28,13 +28,14 @@ import org.springframework.test.context.ContextConfiguration;
*/ */
@ContextConfiguration(classes = { DoubleIDRepositoryRestTemplateIntegrationTests.Config.class }) @ContextConfiguration(classes = { DoubleIDRepositoryRestTemplateIntegrationTests.Config.class })
public class DoubleIDRepositoryRestTemplateIntegrationTests extends DoubleIDRepositoryIntegrationTests { public class DoubleIDRepositoryRestTemplateIntegrationTests extends DoubleIDRepositoryIntegrationTests {
@Configuration @Configuration
@Import({ ElasticsearchRestTemplateConfiguration.class }) @Import({ ElasticsearchRestTemplateConfiguration.class })
@EnableElasticsearchRepositories(considerNestedRepositories = true) @EnableElasticsearchRepositories(considerNestedRepositories = true)
static class Config { static class Config {
@Bean @Bean
IndexNameProvider indexNameProvider() { IndexNameProvider indexNameProvider() {
return new IndexNameProvider(); return new IndexNameProvider("doubleid-reository-es7");
} }
} }
} }

View File

@ -29,13 +29,14 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = { DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests.Config.class }) @ContextConfiguration(classes = { DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests.Config.class })
public class DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests public class DynamicSettingAndMappingEntityRepositoryRestTemplateIntegrationTests
extends DynamicSettingAndMappingEntityRepositoryIntegrationTests { extends DynamicSettingAndMappingEntityRepositoryIntegrationTests {
@Configuration @Configuration
@Import({ ElasticsearchRestTemplateConfiguration.class }) @Import({ ElasticsearchRestTemplateConfiguration.class })
@EnableElasticsearchRepositories(considerNestedRepositories = true) @EnableElasticsearchRepositories(considerNestedRepositories = true)
static class Config { static class Config {
@Bean @Bean
IndexNameProvider indexNameProvider() { IndexNameProvider indexNameProvider() {
return new IndexNameProvider(); return new IndexNameProvider("dynamic-setting-and-mapping-3s7");
} }
} }