Allow explicit index mapping writing on repository startup.

Original Pull Request #2708
Closes #2465
This commit is contained in:
Peter-Josef Meisch 2023-09-23 17:34:36 +02:00 committed by GitHub
parent 3330d65edf
commit 092306aeea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 0 deletions

View File

@ -58,6 +58,13 @@ public @interface Document {
*/ */
boolean createIndex() default true; boolean createIndex() default true;
/**
* If true, the index mapping will be written on repository bootstrapping even when the index already exists. This
* allows for automatically updating the mapping with new properties. Changes on existing properties will lead to an
* error from the Elasticsearch server.
*/
boolean alwaysWriteMapping() default false;
/** /**
* Configuration of version management. * Configuration of version management.
*/ */

View File

@ -187,4 +187,10 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
* @since 5.1 * @since 5.1
*/ */
boolean storeVersionInSource(); boolean storeVersionInSource();
/**
* @return if the mapping should be written to the index on repositry bootstrap even if the index already exists.
* @since 5.2
*/
boolean isAlwaysWriteMapping();
} }

View File

@ -74,6 +74,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
private @Nullable ElasticsearchPersistentProperty indexedIndexNameProperty; private @Nullable ElasticsearchPersistentProperty indexedIndexNameProperty;
private @Nullable Document.VersionType versionType; private @Nullable Document.VersionType versionType;
private boolean createIndexAndMapping; private boolean createIndexAndMapping;
private boolean alwaysWriteMapping;
private final Dynamic dynamic; private final Dynamic dynamic;
private final Map<String, ElasticsearchPersistentProperty> fieldNamePropertyCache = new ConcurrentHashMap<>(); private final Map<String, ElasticsearchPersistentProperty> fieldNamePropertyCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Expression> routingExpressions = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, Expression> routingExpressions = new ConcurrentHashMap<>();
@ -107,6 +108,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
this.indexName = document.indexName(); this.indexName = document.indexName();
this.versionType = document.versionType(); this.versionType = document.versionType();
this.createIndexAndMapping = document.createIndex(); this.createIndexAndMapping = document.createIndex();
this.alwaysWriteMapping = document.alwaysWriteMapping();
this.dynamic = document.dynamic(); this.dynamic = document.dynamic();
this.storeIdInSource = document.storeIdInSource(); this.storeIdInSource = document.storeIdInSource();
this.storeVersionInSource = document.storeVersionInSource(); this.storeVersionInSource = document.storeVersionInSource();
@ -114,6 +116,8 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
this.dynamic = Dynamic.INHERIT; this.dynamic = Dynamic.INHERIT;
this.storeIdInSource = true; this.storeIdInSource = true;
this.storeVersionInSource = true; this.storeVersionInSource = true;
this.createIndexAndMapping = false;
this.alwaysWriteMapping = false;
} }
Routing routingAnnotation = AnnotatedElementUtils.findMergedAnnotation(clazz, Routing.class); Routing routingAnnotation = AnnotatedElementUtils.findMergedAnnotation(clazz, Routing.class);
@ -172,6 +176,10 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
return createIndexAndMapping; return createIndexAndMapping;
} }
public boolean isAlwaysWriteMapping() {
return alwaysWriteMapping;
}
@Override @Override
public FieldNamingStrategy getFieldNamingStrategy() { public FieldNamingStrategy getFieldNamingStrategy() {
return contextConfiguration.getFieldNamingStrategy(); return contextConfiguration.getFieldNamingStrategy();

View File

@ -82,6 +82,8 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
if (shouldCreateIndexAndMapping() && !indexOperations.exists()) { if (shouldCreateIndexAndMapping() && !indexOperations.exists()) {
indexOperations.createWithMapping(); indexOperations.createWithMapping();
} else if (shouldAlwaysWriteMapping()) {
indexOperations.putMapping();
} }
} }
@ -92,6 +94,11 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
return entity.isCreateIndexAndMapping(); return entity.isCreateIndexAndMapping();
} }
private boolean shouldAlwaysWriteMapping() {
return operations.getElasticsearchConverter().getMappingContext()
.getRequiredPersistentEntity(entityClass).isAlwaysWriteMapping();
}
@Override @Override
public Optional<T> findById(ID id) { public Optional<T> findById(ID id) {
return Optional.ofNullable( return Optional.ofNullable(

View File

@ -66,6 +66,8 @@ public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveEla
indexOperations.exists() // indexOperations.exists() //
.flatMap(exists -> exists ? Mono.empty() : indexOperations.createWithMapping()) // .flatMap(exists -> exists ? Mono.empty() : indexOperations.createWithMapping()) //
.block(); .block();
} else if(shouldAlwaysWriteMapping()) {
indexOperations.putMapping().block();
} }
} }
@ -76,6 +78,11 @@ public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveEla
return entity.isCreateIndexAndMapping(); return entity.isCreateIndexAndMapping();
} }
private boolean shouldAlwaysWriteMapping() {
return operations.getElasticsearchConverter().getMappingContext()
.getRequiredPersistentEntity(entityInformation.getJavaType()).isAlwaysWriteMapping();
}
@Override @Override
public <S extends T> Mono<S> save(S entity) { public <S extends T> Mono<S> save(S entity) {