DATAES-305 - Allow to put mapping built from entity class to different index.

Original pull request: #319
This commit is contained in:
xhaggi 2019-09-12 09:56:00 +02:00
parent 6092da6fe7
commit 642d95b5d1
5 changed files with 97 additions and 42 deletions

View File

@ -0,0 +1,52 @@
package org.springframework.data.elasticsearch.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* AbstractElasticsearchTemplate
*
* @author Sascha Woo
*/
public abstract class AbstractElasticsearchTemplate {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class);
protected ElasticsearchConverter elasticsearchConverter;
public AbstractElasticsearchTemplate(ElasticsearchConverter elasticsearchConverter) {
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null.");
this.elasticsearchConverter = elasticsearchConverter;
}
protected String buildMapping(Class<?> clazz) {
// load mapping specified in Mapping annotation if present
if (clazz.isAnnotationPresent(Mapping.class)) {
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
if (!StringUtils.isEmpty(mappingPath)) {
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
if (!StringUtils.isEmpty(mappings)) {
return mappings;
}
} else {
LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
}
}
// build mapping from field annotations
try {
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
return mappingBuilder.buildPropertyMapping(clazz);
} catch (Exception e) {
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
}
}
}

View File

@ -104,6 +104,16 @@ public interface ElasticsearchOperations {
*/
<T> boolean putMapping(Class<T> clazz);
/**
* Create mapping for the given class and put the mapping to the given indexName and type.
*
* @param indexName
* @param type
* @param mappings
* @since 3.2
*/
<T> boolean putMapping(String indexName, String type, Class<T> clazz);
/**
* Create mapping for a given indexName and type
*

View File

@ -143,12 +143,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @author Mathias Teier
* @author Gyula Attila Csorogi
*/
public class ElasticsearchRestTemplate
public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
implements ElasticsearchOperations, EsClient<RestHighLevelClient>, ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
private RestHighLevelClient client;
private ElasticsearchConverter elasticsearchConverter;
private ResultsMapper resultsMapper;
private String searchTimeout;
@ -176,9 +175,10 @@ public class ElasticsearchRestTemplate
public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter,
ResultsMapper resultsMapper) {
super(elasticsearchConverter);
Assert.notNull(client, "Client must not be null!");
Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!");
Assert.notNull(resultsMapper, "ResultsMapper must not be null!");
this.client = client;
@ -254,23 +254,7 @@ public class ElasticsearchRestTemplate
@Override
public <T> boolean putMapping(Class<T> clazz) {
if (clazz.isAnnotationPresent(Mapping.class)) {
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
if (hasText(mappingPath)) {
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
if (hasText(mappings)) {
return putMapping(clazz, mappings);
}
} else {
logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
}
}
try {
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
} catch (Exception e) {
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
}
return putMapping(clazz, buildMapping(clazz));
}
@Override
@ -279,6 +263,11 @@ public class ElasticsearchRestTemplate
mapping);
}
@Override
public <T> boolean putMapping(String indexName, String type, Class<T> clazz) {
return putMapping(indexName, type, buildMapping(clazz));
}
@Override
public boolean putMapping(String indexName, String type, Object mapping) {
Assert.notNull(indexName, "No index defined for putMapping()");

View File

@ -82,7 +82,6 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@ -124,7 +123,7 @@ import org.springframework.util.StringUtils;
* @author Farid Azaza
* @author Gyula Attila Csorogi
*/
public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
public class ElasticsearchTemplate extends AbstractElasticsearchTemplate implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
private static final Logger QUERY_LOGGER = LoggerFactory
.getLogger("org.springframework.data.elasticsearch.core.QUERY");
@ -132,7 +131,6 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
private static final String FIELD_SCORE = "_score";
private Client client;
private ElasticsearchConverter elasticsearchConverter;
private ResultsMapper resultsMapper;
private String searchTimeout;
@ -160,13 +158,13 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter,
ResultsMapper resultsMapper) {
super(elasticsearchConverter);
Assert.notNull(client, "Client must not be null!");
Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!");
Assert.notNull(resultsMapper, "ResultsMapper must not be null!");
this.client = client;
this.elasticsearchConverter = elasticsearchConverter;
this.resultsMapper = resultsMapper;
}
@ -221,23 +219,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
@Override
public <T> boolean putMapping(Class<T> clazz) {
if (clazz.isAnnotationPresent(Mapping.class)) {
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
if (!StringUtils.isEmpty(mappingPath)) {
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
if (!StringUtils.isEmpty(mappings)) {
return putMapping(clazz, mappings);
}
} else {
LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
}
}
try {
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
} catch (Exception e) {
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
}
return putMapping(clazz, buildMapping(clazz));
}
@Override
@ -246,6 +228,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
mapping);
}
@Override
public <T> boolean putMapping(String indexName, String type, Class<T> clazz) {
return putMapping(indexName, type, buildMapping(clazz));
}
@Override
public boolean putMapping(String indexName, String type, Object mapping) {
Assert.notNull(indexName, "No index defined for putMapping()");

View File

@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core;
import static org.apache.commons.lang.RandomStringUtils.*;
import static org.assertj.core.api.Assertions.*;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.hamcrest.CoreMatchers.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
@ -1438,6 +1439,22 @@ public class ElasticsearchTemplateTests {
assertThat(elasticsearchTemplate.putMapping(entity)).isTrue();
}
@Test // DATAES-305
public void shouldPutMappingWithCustomIndexName() throws Exception {
// given
Class<SampleEntity> entity = SampleEntity.class;
elasticsearchTemplate.deleteIndex(INDEX_1_NAME);
elasticsearchTemplate.createIndex(INDEX_1_NAME);
// when
elasticsearchTemplate.putMapping(INDEX_1_NAME, TYPE_NAME, entity);
// then
Map<String, Object> mapping = elasticsearchTemplate.getMapping(INDEX_1_NAME, TYPE_NAME);
assertThat(mapping.get("properties")).isNotNull();
}
@Test
public void shouldDeleteIndexForGivenEntity() {