Skip to content

Commit 2f5773a

Browse files
authored
Create index with mapping in one step.
Original Pull Request spring-projects#1723 Closes spring-projects#1718
1 parent e4c7b96 commit 2f5773a

11 files changed

+141
-43
lines changed

src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java

+14-6
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public boolean create() {
9696
settings = createSettings(boundClass);
9797
}
9898

99-
return doCreate(getIndexCoordinates(), settings);
99+
return doCreate(getIndexCoordinates(), settings, null);
100100
}
101101

102102
@Override
@@ -119,12 +119,22 @@ public Document createSettings(Class<?> clazz) {
119119
return settings;
120120
}
121121

122+
@Override
123+
public boolean createWithMapping() {
124+
return doCreate(getIndexCoordinates(), createSettings(), createMapping());
125+
}
126+
122127
@Override
123128
public boolean create(Document settings) {
124-
return doCreate(getIndexCoordinates(), settings);
129+
return doCreate(getIndexCoordinates(), settings, null);
125130
}
126131

127-
protected abstract boolean doCreate(IndexCoordinates index, @Nullable Document settings);
132+
@Override
133+
public boolean create(Document settings, Document mapping) {
134+
return doCreate(getIndexCoordinates(), settings, mapping);
135+
}
136+
137+
protected abstract boolean doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping);
128138

129139
@Override
130140
public boolean delete() {
@@ -242,9 +252,7 @@ protected Document buildMapping(Class<?> clazz) {
242252
}
243253

244254
// build mapping from field annotations
245-
try
246-
247-
{
255+
try {
248256
String mapping = new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz);
249257
return Document.parse(mapping);
250258
} catch (Exception e) {

src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ public DefaultIndexOperations(ElasticsearchRestTemplate restTemplate, IndexCoord
8181
}
8282

8383
@Override
84-
protected boolean doCreate(IndexCoordinates index, @Nullable Document settings) {
85-
CreateIndexRequest request = requestFactory.createIndexRequest(index, settings);
84+
protected boolean doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
85+
CreateIndexRequest request = requestFactory.createIndexRequest(index, settings, mapping);
8686
return restTemplate.execute(client -> client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged());
8787
}
8888

src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java

+22-9
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626

2727
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
2828
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
29-
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
3029
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
3130
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
3231
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
3332
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
3433
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest;
3534
import org.elasticsearch.client.GetAliasesResponse;
35+
import org.elasticsearch.client.indices.CreateIndexRequest;
3636
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
3737
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
3838
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
@@ -101,23 +101,36 @@ public DefaultReactiveIndexOperations(ReactiveElasticsearchOperations operations
101101
@Override
102102
public Mono<Boolean> create() {
103103

104-
String indexName = getIndexCoordinates().getIndexName();
104+
IndexCoordinates index = getIndexCoordinates();
105105

106106
if (boundClass != null) {
107-
return createSettings(boundClass).flatMap(settings -> doCreate(indexName, settings));
107+
return createSettings(boundClass).flatMap(settings -> doCreate(index, settings, null));
108108
} else {
109-
return doCreate(indexName, null);
109+
return doCreate(index, null, null);
110110
}
111111
}
112112

113+
@Override
114+
public Mono<Boolean> createWithMapping() {
115+
return createSettings() //
116+
.flatMap(settings -> //
117+
createMapping().flatMap(mapping -> //
118+
doCreate(getIndexCoordinates(), settings, mapping))); //
119+
}
120+
113121
@Override
114122
public Mono<Boolean> create(Document settings) {
115-
return doCreate(getIndexCoordinates().getIndexName(), settings);
123+
return doCreate(getIndexCoordinates(), settings, null);
116124
}
117125

118-
private Mono<Boolean> doCreate(String indexName, @Nullable Document settings) {
126+
@Override
127+
public Mono<Boolean> create(Document settings, Document mapping) {
128+
throw new UnsupportedOperationException("not implemented");
129+
}
119130

120-
CreateIndexRequest request = requestFactory.createIndexRequestReactive(indexName, settings);
131+
private Mono<Boolean> doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
132+
133+
CreateIndexRequest request = requestFactory.createIndexRequest(index, settings, mapping);
121134
return Mono.from(operations.executeWithIndicesClient(client -> client.createIndex(request)));
122135
}
123136

@@ -309,9 +322,9 @@ public IndexCoordinates getIndexCoordinates() {
309322
@Override
310323
public Flux<IndexInformation> getInformation(IndexCoordinates index) {
311324

312-
Assert.notNull(index, "index must not be null");
325+
Assert.notNull(index, "index must not be null");
313326

314-
org.elasticsearch.client.indices.GetIndexRequest getIndexRequest = requestFactory.getIndexRequest(index);
327+
org.elasticsearch.client.indices.GetIndexRequest getIndexRequest = requestFactory.getIndexRequest(index);
315328
return Mono
316329
.from(operations.executeWithIndicesClient(
317330
client -> client.getIndex(getIndexRequest).map(ResponseConverter::getIndexInformations)))

src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ public DefaultTransportIndexOperations(Client client, ElasticsearchConverter ela
9090
}
9191

9292
@Override
93-
protected boolean doCreate(IndexCoordinates index, @Nullable Document settings) {
93+
protected boolean doCreate(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
9494
CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, index,
95-
settings);
95+
settings, mapping);
9696
return createIndexRequestBuilder.execute().actionGet().isAcknowledged();
9797
}
9898

src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java

+31-13
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,31 @@ public interface IndexOperations {
5555
boolean create();
5656

5757
/**
58-
* Create an index for given Settings.
58+
* Create an index for given settings.
5959
*
6060
* @param settings the index settings
6161
* @return {@literal true} if the index was created
6262
*/
6363
boolean create(Document settings);
6464

65+
/**
66+
* Create an index for given settings and mapping.
67+
*
68+
* @param settings the index settings
69+
* @param mapping the index mapping
70+
* @return {@literal true} if the index was created
71+
* @since 4.2
72+
*/
73+
boolean create(Document settings, Document mapping);
74+
75+
/**
76+
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
77+
*
78+
* @return {@literal true} if the index was created
79+
* @since 4.2
80+
*/
81+
boolean createWithMapping();
82+
6583
/**
6684
* Deletes the index this {@link IndexOperations} is bound to
6785
*
@@ -82,7 +100,7 @@ public interface IndexOperations {
82100
void refresh();
83101
// endregion
84102

85-
// region mappings
103+
// region mapping
86104
/**
87105
* Creates the index mapping for the entity this IndexOperations is bound to.
88106
*
@@ -309,16 +327,16 @@ default boolean deleteTemplate(String templateName) {
309327

310328
// endregion
311329

312-
//region index information
313-
/**
314-
* Gets the {@link IndexInformation} for the indices defined by {@link #getIndexCoordinates()}.
315-
*
316-
* @return a list of {@link IndexInformation}
317-
* @since 4.2
318-
*/
319-
default List<IndexInformation> getInformation() {
320-
return getInformation(getIndexCoordinates());
321-
}
330+
// region index information
331+
/**
332+
* Gets the {@link IndexInformation} for the indices defined by {@link #getIndexCoordinates()}.
333+
*
334+
* @return a list of {@link IndexInformation}
335+
* @since 4.2
336+
*/
337+
default List<IndexInformation> getInformation() {
338+
return getInformation(getIndexCoordinates());
339+
}
322340

323341
/**
324342
* Gets the {@link IndexInformation} for the indices defined by #index.
@@ -328,7 +346,7 @@ default List<IndexInformation> getInformation() {
328346
* @since 4.2
329347
*/
330348
List<IndexInformation> getInformation(IndexCoordinates index);
331-
//endregion
349+
// endregion
332350

333351
// region helper functions
334352
/**

src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java

+20
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,26 @@ public interface ReactiveIndexOperations {
5858
*/
5959
Mono<Boolean> create(Document settings);
6060

61+
/**
62+
* Create an index for given settings and mapping.
63+
*
64+
* @param settings the index settings
65+
* @param mapping the index mapping
66+
* @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg.
67+
* the index already exist.
68+
* @since 4.2
69+
*/
70+
Mono<Boolean> create(Document settings, Document mapping);
71+
72+
/**
73+
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
74+
*
75+
* @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg.
76+
* the index already exist.
77+
* @since 4.2
78+
*/
79+
Mono<Boolean> createWithMapping();
80+
6181
/**
6282
* Delete an index.
6383
*

src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java

+36
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,29 @@ public BulkRequestBuilder bulkRequestBuilder(Client client, List<?> queries, Bul
355355
* @return request
356356
*/
357357
public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings) {
358+
return createIndexRequest(index, settings, null);
359+
}
360+
361+
/**
362+
* creates a CreateIndexRequest from the rest-high-level-client library.
363+
*
364+
* @param index name of the index
365+
* @param settings optional settings
366+
* @param mapping optional mapping
367+
* @return request
368+
* @since 4.2
369+
*/
370+
public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings, @Nullable Document mapping) {
358371
CreateIndexRequest request = new CreateIndexRequest(index.getIndexName());
359372

360373
if (settings != null && !settings.isEmpty()) {
361374
request.settings(settings);
362375
}
376+
377+
if (mapping != null && !mapping.isEmpty()) {
378+
request.mapping(mapping);
379+
}
380+
363381
return request;
364382
}
365383

@@ -395,6 +413,24 @@ public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, IndexC
395413
return createIndexRequestBuilder;
396414
}
397415

416+
public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, IndexCoordinates index,
417+
@Nullable Document settings, @Nullable Document mapping) {
418+
419+
String indexName = index.getIndexName();
420+
CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName);
421+
422+
if (settings != null && !settings.isEmpty()) {
423+
424+
createIndexRequestBuilder.setSettings(settings);
425+
}
426+
427+
if (mapping != null && !mapping.isEmpty()) {
428+
createIndexRequestBuilder.addMapping(IndexCoordinates.TYPE, mapping);
429+
}
430+
431+
return createIndexRequestBuilder;
432+
}
433+
398434
/**
399435
* creates a GetIndexRequest from the rest-high-level-client library.
400436
*

src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ public SimpleElasticsearchRepository(ElasticsearchEntityInformation<T, ID> metad
9191
this.indexOperations = operations.indexOps(this.entityClass);
9292

9393
if (shouldCreateIndexAndMapping() && !indexOperations.exists()) {
94-
indexOperations.create();
95-
indexOperations.putMapping(entityClass);
94+
indexOperations.createWithMapping();
9695
}
9796
}
9897

src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ private void createIndexAndMappingIfNeeded() {
6565

6666
if (shouldCreateIndexAndMapping()) {
6767
indexOperations.exists() //
68-
.flatMap(exists -> exists ? Mono.empty() : indexOperations.create()) //
69-
.flatMap(success -> success ? indexOperations.putMapping() : Mono.empty()) //
68+
.flatMap(exists -> exists ? Mono.empty() : indexOperations.createWithMapping()) //
7069
.block();
7170
}
7271
}

src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateIntegrationTests.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1114,15 +1114,14 @@ void shouldReturnExplanationWhenRequested() {
11141114
}).verifyComplete();
11151115
}
11161116

1117-
@Test // #1646
1117+
@Test // #1646, #1718
11181118
@DisplayName("should return a list of info for specific index")
11191119
void shouldReturnInformationListOfAllIndices() {
11201120
String indexName = "test-index-reactive-information-list";
11211121
String aliasName = "testindexinformationindex";
11221122
ReactiveIndexOperations indexOps = template.indexOps(EntityWithSettingsAndMappingsReactive.class);
11231123

1124-
indexOps.create().block();
1125-
indexOps.putMapping().block();
1124+
indexOps.createWithMapping().block();
11261125

11271126
AliasActionParameters parameters = AliasActionParameters.builder().withAliases(aliasName).withIndices(indexName)
11281127
.withIsHidden(false).withIsWriteIndex(false).withRouting("indexrouting").withSearchRouting("searchrouting")

src/test/java/org/springframework/data/elasticsearch/core/index/IndexOperationIntegrationTests.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,14 @@ void setUp() {
5454
operations.indexOps(EntityWithSettingsAndMappings.class).delete();
5555
}
5656

57-
@Test // #1646
57+
@Test // #1646, #1718
5858
@DisplayName("should return a list of info for specific index")
5959
void shouldReturnInformationList() throws JSONException {
6060
IndexOperations indexOps = operations.indexOps(EntityWithSettingsAndMappings.class);
6161

6262
String aliasName = "testindexinformationindex";
6363

64-
indexOps.create();
65-
indexOps.putMapping();
64+
indexOps.createWithMapping();
6665

6766
AliasActionParameters parameters = AliasActionParameters.builder().withAliases(aliasName).withIndices(INDEX_NAME)
6867
.withIsHidden(false).withIsWriteIndex(false).withRouting("indexrouting").withSearchRouting("searchrouting")
@@ -88,7 +87,14 @@ void shouldReturnInformationList() throws JSONException {
8887
assertThat(aliasData.getIndexRouting()).isEqualTo("indexrouting");
8988
assertThat(aliasData.getSearchRouting()).isEqualTo("searchrouting");
9089

91-
String expectedMappings = "{\"properties\":{\"email\":{\"type\":\"text\",\"analyzer\":\"emailAnalyzer\"}}}";
90+
String expectedMappings = "{\n" + //
91+
" \"properties\": {\n" + //
92+
" \"email\": {\n" + //
93+
" \"type\": \"text\",\n" + //
94+
" \"analyzer\": \"emailAnalyzer\"\n" + //
95+
" }\n" + //
96+
" }\n" + //
97+
"}"; //
9298
JSONAssert.assertEquals(expectedMappings, indexInformation.getMapping().toJson(), false);
9399
}
94100

0 commit comments

Comments
 (0)