Create index with mapping in one step.

Original Pull Request #1723 
Closes #1718
This commit is contained in:
Peter-Josef Meisch 2021-03-06 18:42:57 +01:00 committed by GitHub
parent e4c7b968e1
commit 2f5773a5ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 143 additions and 45 deletions

View File

@ -96,7 +96,7 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations {
settings = createSettings(boundClass); settings = createSettings(boundClass);
} }
return doCreate(getIndexCoordinates(), settings); return doCreate(getIndexCoordinates(), settings, null);
} }
@Override @Override
@ -120,11 +120,21 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations {
} }
@Override @Override
public boolean create(Document settings) { public boolean createWithMapping() {
return doCreate(getIndexCoordinates(), settings); return doCreate(getIndexCoordinates(), createSettings(), createMapping());
} }
protected abstract boolean doCreate(IndexCoordinates index, @Nullable Document settings); @Override
public boolean create(Document settings) {
return doCreate(getIndexCoordinates(), settings, null);
}
@Override
public boolean create(Document settings, Document mapping) {
return doCreate(getIndexCoordinates(), settings, mapping);
}
protected abstract boolean doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping);
@Override @Override
public boolean delete() { public boolean delete() {
@ -242,9 +252,7 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations {
} }
// build mapping from field annotations // build mapping from field annotations
try try {
{
String mapping = new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz); String mapping = new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz);
return Document.parse(mapping); return Document.parse(mapping);
} catch (Exception e) { } catch (Exception e) {

View File

@ -81,8 +81,8 @@ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements I
} }
@Override @Override
protected boolean doCreate(IndexCoordinates index, @Nullable Document settings) { protected boolean doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
CreateIndexRequest request = requestFactory.createIndexRequest(index, settings); CreateIndexRequest request = requestFactory.createIndexRequest(index, settings, mapping);
return restTemplate.execute(client -> client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged()); return restTemplate.execute(client -> client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged());
} }

View File

@ -26,13 +26,13 @@ import java.util.Set;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest;
import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexTemplatesRequest; import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
import org.elasticsearch.client.indices.IndexTemplatesExistRequest; import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.client.indices.PutIndexTemplateRequest;
@ -101,23 +101,36 @@ class DefaultReactiveIndexOperations implements ReactiveIndexOperations {
@Override @Override
public Mono<Boolean> create() { public Mono<Boolean> create() {
String indexName = getIndexCoordinates().getIndexName(); IndexCoordinates index = getIndexCoordinates();
if (boundClass != null) { if (boundClass != null) {
return createSettings(boundClass).flatMap(settings -> doCreate(indexName, settings)); return createSettings(boundClass).flatMap(settings -> doCreate(index, settings, null));
} else { } else {
return doCreate(indexName, null); return doCreate(index, null, null);
} }
} }
@Override @Override
public Mono<Boolean> create(Document settings) { public Mono<Boolean> createWithMapping() {
return doCreate(getIndexCoordinates().getIndexName(), settings); return createSettings() //
.flatMap(settings -> //
createMapping().flatMap(mapping -> //
doCreate(getIndexCoordinates(), settings, mapping))); //
} }
private Mono<Boolean> doCreate(String indexName, @Nullable Document settings) { @Override
public Mono<Boolean> create(Document settings) {
return doCreate(getIndexCoordinates(), settings, null);
}
CreateIndexRequest request = requestFactory.createIndexRequestReactive(indexName, settings); @Override
public Mono<Boolean> create(Document settings, Document mapping) {
throw new UnsupportedOperationException("not implemented");
}
private Mono<Boolean> doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
CreateIndexRequest request = requestFactory.createIndexRequest(index, settings, mapping);
return Mono.from(operations.executeWithIndicesClient(client -> client.createIndex(request))); return Mono.from(operations.executeWithIndicesClient(client -> client.createIndex(request)));
} }
@ -309,9 +322,9 @@ class DefaultReactiveIndexOperations implements ReactiveIndexOperations {
@Override @Override
public Flux<IndexInformation> getInformation(IndexCoordinates index) { public Flux<IndexInformation> getInformation(IndexCoordinates index) {
Assert.notNull(index, "index must not be null"); Assert.notNull(index, "index must not be null");
org.elasticsearch.client.indices.GetIndexRequest getIndexRequest = requestFactory.getIndexRequest(index); org.elasticsearch.client.indices.GetIndexRequest getIndexRequest = requestFactory.getIndexRequest(index);
return Mono return Mono
.from(operations.executeWithIndicesClient( .from(operations.executeWithIndicesClient(
client -> client.getIndex(getIndexRequest).map(ResponseConverter::getIndexInformations))) client -> client.getIndex(getIndexRequest).map(ResponseConverter::getIndexInformations)))

View File

@ -90,9 +90,9 @@ class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations imp
} }
@Override @Override
protected boolean doCreate(IndexCoordinates index, @Nullable Document settings) { protected boolean doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, index, CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, index,
settings); settings, mapping);
return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); return createIndexRequestBuilder.execute().actionGet().isAcknowledged();
} }

View File

@ -55,13 +55,31 @@ public interface IndexOperations {
boolean create(); boolean create();
/** /**
* Create an index for given Settings. * Create an index for given settings.
* *
* @param settings the index settings * @param settings the index settings
* @return {@literal true} if the index was created * @return {@literal true} if the index was created
*/ */
boolean create(Document settings); boolean create(Document settings);
/**
* Create an index for given settings and mapping.
*
* @param settings the index settings
* @param mapping the index mapping
* @return {@literal true} if the index was created
* @since 4.2
*/
boolean create(Document settings, Document mapping);
/**
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
*
* @return {@literal true} if the index was created
* @since 4.2
*/
boolean createWithMapping();
/** /**
* Deletes the index this {@link IndexOperations} is bound to * Deletes the index this {@link IndexOperations} is bound to
* *
@ -82,7 +100,7 @@ public interface IndexOperations {
void refresh(); void refresh();
// endregion // endregion
// region mappings // region mapping
/** /**
* Creates the index mapping for the entity this IndexOperations is bound to. * Creates the index mapping for the entity this IndexOperations is bound to.
* *
@ -309,16 +327,16 @@ public interface IndexOperations {
// endregion // endregion
//region index information // region index information
/** /**
* Gets the {@link IndexInformation} for the indices defined by {@link #getIndexCoordinates()}. * Gets the {@link IndexInformation} for the indices defined by {@link #getIndexCoordinates()}.
* *
* @return a list of {@link IndexInformation} * @return a list of {@link IndexInformation}
* @since 4.2 * @since 4.2
*/ */
default List<IndexInformation> getInformation() { default List<IndexInformation> getInformation() {
return getInformation(getIndexCoordinates()); return getInformation(getIndexCoordinates());
} }
/** /**
* Gets the {@link IndexInformation} for the indices defined by #index. * Gets the {@link IndexInformation} for the indices defined by #index.
@ -328,7 +346,7 @@ public interface IndexOperations {
* @since 4.2 * @since 4.2
*/ */
List<IndexInformation> getInformation(IndexCoordinates index); List<IndexInformation> getInformation(IndexCoordinates index);
//endregion // endregion
// region helper functions // region helper functions
/** /**

View File

@ -58,6 +58,26 @@ public interface ReactiveIndexOperations {
*/ */
Mono<Boolean> create(Document settings); Mono<Boolean> create(Document settings);
/**
* Create an index for given settings and mapping.
*
* @param settings the index settings
* @param mapping the index mapping
* @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg.
* the index already exist.
* @since 4.2
*/
Mono<Boolean> create(Document settings, Document mapping);
/**
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
*
* @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg.
* the index already exist.
* @since 4.2
*/
Mono<Boolean> createWithMapping();
/** /**
* Delete an index. * Delete an index.
* *

View File

@ -355,11 +355,29 @@ class RequestFactory {
* @return request * @return request
*/ */
public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings) { public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings) {
return createIndexRequest(index, settings, null);
}
/**
* creates a CreateIndexRequest from the rest-high-level-client library.
*
* @param index name of the index
* @param settings optional settings
* @param mapping optional mapping
* @return request
* @since 4.2
*/
public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
CreateIndexRequest request = new CreateIndexRequest(index.getIndexName()); CreateIndexRequest request = new CreateIndexRequest(index.getIndexName());
if (settings != null && !settings.isEmpty()) { if (settings != null && !settings.isEmpty()) {
request.settings(settings); request.settings(settings);
} }
if (mapping != null && !mapping.isEmpty()) {
request.mapping(mapping);
}
return request; return request;
} }
@ -395,6 +413,24 @@ class RequestFactory {
return createIndexRequestBuilder; return createIndexRequestBuilder;
} }
public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, IndexCoordinates index,
@Nullable Document settings, @Nullable Document mapping) {
String indexName = index.getIndexName();
CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName);
if (settings != null && !settings.isEmpty()) {
createIndexRequestBuilder.setSettings(settings);
}
if (mapping != null && !mapping.isEmpty()) {
createIndexRequestBuilder.addMapping(IndexCoordinates.TYPE, mapping);
}
return createIndexRequestBuilder;
}
/** /**
* creates a GetIndexRequest from the rest-high-level-client library. * creates a GetIndexRequest from the rest-high-level-client library.
* *

View File

@ -91,8 +91,7 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
this.indexOperations = operations.indexOps(this.entityClass); this.indexOperations = operations.indexOps(this.entityClass);
if (shouldCreateIndexAndMapping() && !indexOperations.exists()) { if (shouldCreateIndexAndMapping() && !indexOperations.exists()) {
indexOperations.create(); indexOperations.createWithMapping();
indexOperations.putMapping(entityClass);
} }
} }

View File

@ -65,8 +65,7 @@ public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveEla
if (shouldCreateIndexAndMapping()) { if (shouldCreateIndexAndMapping()) {
indexOperations.exists() // indexOperations.exists() //
.flatMap(exists -> exists ? Mono.empty() : indexOperations.create()) // .flatMap(exists -> exists ? Mono.empty() : indexOperations.createWithMapping()) //
.flatMap(success -> success ? indexOperations.putMapping() : Mono.empty()) //
.block(); .block();
} }
} }

View File

@ -1114,15 +1114,14 @@ public class ReactiveElasticsearchTemplateIntegrationTests {
}).verifyComplete(); }).verifyComplete();
} }
@Test // #1646 @Test // #1646, #1718
@DisplayName("should return a list of info for specific index") @DisplayName("should return a list of info for specific index")
void shouldReturnInformationListOfAllIndices() { void shouldReturnInformationListOfAllIndices() {
String indexName = "test-index-reactive-information-list"; String indexName = "test-index-reactive-information-list";
String aliasName = "testindexinformationindex"; String aliasName = "testindexinformationindex";
ReactiveIndexOperations indexOps = template.indexOps(EntityWithSettingsAndMappingsReactive.class); ReactiveIndexOperations indexOps = template.indexOps(EntityWithSettingsAndMappingsReactive.class);
indexOps.create().block(); indexOps.createWithMapping().block();
indexOps.putMapping().block();
AliasActionParameters parameters = AliasActionParameters.builder().withAliases(aliasName).withIndices(indexName) AliasActionParameters parameters = AliasActionParameters.builder().withAliases(aliasName).withIndices(indexName)
.withIsHidden(false).withIsWriteIndex(false).withRouting("indexrouting").withSearchRouting("searchrouting") .withIsHidden(false).withIsWriteIndex(false).withRouting("indexrouting").withSearchRouting("searchrouting")

View File

@ -54,15 +54,14 @@ public class IndexOperationIntegrationTests {
operations.indexOps(EntityWithSettingsAndMappings.class).delete(); operations.indexOps(EntityWithSettingsAndMappings.class).delete();
} }
@Test // #1646 @Test // #1646, #1718
@DisplayName("should return a list of info for specific index") @DisplayName("should return a list of info for specific index")
void shouldReturnInformationList() throws JSONException { void shouldReturnInformationList() throws JSONException {
IndexOperations indexOps = operations.indexOps(EntityWithSettingsAndMappings.class); IndexOperations indexOps = operations.indexOps(EntityWithSettingsAndMappings.class);
String aliasName = "testindexinformationindex"; String aliasName = "testindexinformationindex";
indexOps.create(); indexOps.createWithMapping();
indexOps.putMapping();
AliasActionParameters parameters = AliasActionParameters.builder().withAliases(aliasName).withIndices(INDEX_NAME) AliasActionParameters parameters = AliasActionParameters.builder().withAliases(aliasName).withIndices(INDEX_NAME)
.withIsHidden(false).withIsWriteIndex(false).withRouting("indexrouting").withSearchRouting("searchrouting") .withIsHidden(false).withIsWriteIndex(false).withRouting("indexrouting").withSearchRouting("searchrouting")
@ -88,7 +87,14 @@ public class IndexOperationIntegrationTests {
assertThat(aliasData.getIndexRouting()).isEqualTo("indexrouting"); assertThat(aliasData.getIndexRouting()).isEqualTo("indexrouting");
assertThat(aliasData.getSearchRouting()).isEqualTo("searchrouting"); assertThat(aliasData.getSearchRouting()).isEqualTo("searchrouting");
String expectedMappings = "{\"properties\":{\"email\":{\"type\":\"text\",\"analyzer\":\"emailAnalyzer\"}}}"; String expectedMappings = "{\n" + //
" \"properties\": {\n" + //
" \"email\": {\n" + //
" \"type\": \"text\",\n" + //
" \"analyzer\": \"emailAnalyzer\"\n" + //
" }\n" + //
" }\n" + //
"}"; //
JSONAssert.assertEquals(expectedMappings, indexInformation.getMapping().toJson(), false); JSONAssert.assertEquals(expectedMappings, indexInformation.getMapping().toJson(), false);
} }