mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-28 14:52:20 +00:00
DATAES-86 - Add dynamic mapping(json) using @Mapping annotation
This commit is contained in:
parent
8c63f3ee22
commit
9ce87f147a
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
import org.springframework.data.annotation.Persistent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elasticsearch Mapping
|
||||||
|
*
|
||||||
|
* @author Mohsin Husen
|
||||||
|
*/
|
||||||
|
@Persistent
|
||||||
|
@Inherited
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
public @interface Mapping {
|
||||||
|
|
||||||
|
String mappingPath() default "";
|
||||||
|
|
||||||
|
}
|
@ -75,6 +75,7 @@ import org.springframework.data.domain.Page;
|
|||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
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.annotations.Setting;
|
||||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||||
@ -138,6 +139,17 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> boolean putMapping(Class<T> clazz) {
|
public <T> boolean putMapping(Class<T> clazz) {
|
||||||
|
if (clazz.isAnnotationPresent(Mapping.class)) {
|
||||||
|
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
|
||||||
|
if (isNotBlank(mappingPath)) {
|
||||||
|
String mappings = readFileFromClasspath(mappingPath);
|
||||||
|
if (isNotBlank(mappings)) {
|
||||||
|
return putMapping(clazz, mappings);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
|
||||||
|
}
|
||||||
|
}
|
||||||
ElasticsearchPersistentEntity<T> persistentEntity = getPersistentEntityFor(clazz);
|
ElasticsearchPersistentEntity<T> persistentEntity = getPersistentEntityFor(clazz);
|
||||||
XContentBuilder xContentBuilder = null;
|
XContentBuilder xContentBuilder = null;
|
||||||
try {
|
try {
|
||||||
|
@ -16,24 +16,21 @@
|
|||||||
package org.springframework.data.elasticsearch.entities;
|
package org.springframework.data.elasticsearch.entities;
|
||||||
|
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.*;
|
||||||
import org.springframework.data.elasticsearch.annotations.Field;
|
|
||||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
|
||||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample SettingEntity for test out dynamic setting using @Setting Annotation
|
* Sample DynamicSettingAndMappingEntity for test out dynamic setting using @Setting Annotation
|
||||||
*
|
*
|
||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
*/
|
*/
|
||||||
@Setting(settingPath = "/settings/test-settings.json")
|
|
||||||
@Document(indexName = "test-setting-index", type = "test-setting-type")
|
@Document(indexName = "test-setting-index", type = "test-setting-type")
|
||||||
public class SettingEntity {
|
@Setting(settingPath = "/settings/test-settings.json")
|
||||||
|
@Mapping(mappingPath = "/mappings/test-mappings.json")
|
||||||
|
public class DynamicSettingAndMappingEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
@Field(type = FieldType.String, searchAnalyzer = "emailAnalyzer", indexAnalyzer = "emailAnalyzer")
|
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
@ -15,14 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.repositories.setting;
|
package org.springframework.data.elasticsearch.repositories.setting;
|
||||||
|
|
||||||
import org.springframework.data.elasticsearch.entities.SettingEntity;
|
import org.springframework.data.elasticsearch.entities.DynamicSettingAndMappingEntity;
|
||||||
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
|
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SettingEntityRepository
|
* DynamicSettingAndMappingEntityRepository
|
||||||
*
|
*
|
||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
*/
|
*/
|
||||||
public interface SettingEntityRepository extends ElasticsearchCrudRepository<SettingEntity, String> {
|
public interface DynamicSettingAndMappingEntityRepository extends ElasticsearchCrudRepository<DynamicSettingAndMappingEntity, String> {
|
||||||
|
|
||||||
}
|
}
|
@ -30,31 +30,31 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
||||||
import org.springframework.data.elasticsearch.entities.SettingEntity;
|
import org.springframework.data.elasticsearch.entities.DynamicSettingAndMappingEntity;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SettingEntityRepositoryTest
|
* DynamicSettingAndMappingEntityRepositoryTests
|
||||||
*
|
*
|
||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration("classpath:dynamic-settings-test.xml")
|
@ContextConfiguration("classpath:dynamic-settings-test.xml")
|
||||||
public class SettingEntityRepositoryTest {
|
public class DynamicSettingAndMappingEntityRepositoryTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SettingEntityRepository repository;
|
private DynamicSettingAndMappingEntityRepository repository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ElasticsearchTemplate elasticsearchTemplate;
|
private ElasticsearchTemplate elasticsearchTemplate;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
elasticsearchTemplate.deleteIndex(SettingEntity.class);
|
elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class);
|
||||||
elasticsearchTemplate.createIndex(SettingEntity.class);
|
elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class);
|
||||||
elasticsearchTemplate.putMapping(SettingEntity.class);
|
elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class);
|
||||||
elasticsearchTemplate.refresh(SettingEntity.class, true);
|
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -66,8 +66,8 @@ public class SettingEntityRepositoryTest {
|
|||||||
//delete , create and apply mapping in before method
|
//delete , create and apply mapping in before method
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(elasticsearchTemplate.indexExists(SettingEntity.class), is(true));
|
assertThat(elasticsearchTemplate.indexExists(DynamicSettingAndMappingEntity.class), is(true));
|
||||||
Map map = elasticsearchTemplate.getSetting(SettingEntity.class);
|
Map map = elasticsearchTemplate.getSetting(DynamicSettingAndMappingEntity.class);
|
||||||
assertThat(map.containsKey("index.number_of_replicas"), is(true));
|
assertThat(map.containsKey("index.number_of_replicas"), is(true));
|
||||||
assertThat(map.containsKey("index.number_of_shards"), is(true));
|
assertThat(map.containsKey("index.number_of_shards"), is(true));
|
||||||
assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer"), is(true));
|
assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer"), is(true));
|
||||||
@ -82,32 +82,32 @@ public class SettingEntityRepositoryTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() {
|
public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() {
|
||||||
//given
|
//given
|
||||||
SettingEntity settingEntity1 = new SettingEntity();
|
DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity1 = new DynamicSettingAndMappingEntity();
|
||||||
settingEntity1.setId(RandomStringUtils.randomNumeric(5));
|
dynamicSettingAndMappingEntity1.setId(RandomStringUtils.randomNumeric(5));
|
||||||
settingEntity1.setName("test-setting1");
|
dynamicSettingAndMappingEntity1.setName("test-setting1");
|
||||||
settingEntity1.setEmail("test_setting1@test.com");
|
dynamicSettingAndMappingEntity1.setEmail("test_setting1@test.com");
|
||||||
|
|
||||||
repository.save(settingEntity1);
|
repository.save(dynamicSettingAndMappingEntity1);
|
||||||
|
|
||||||
SettingEntity settingEntity2 = new SettingEntity();
|
DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity2 = new DynamicSettingAndMappingEntity();
|
||||||
settingEntity2.setId(RandomStringUtils.randomNumeric(5));
|
dynamicSettingAndMappingEntity2.setId(RandomStringUtils.randomNumeric(5));
|
||||||
settingEntity2.setName("test-setting2");
|
dynamicSettingAndMappingEntity2.setName("test-setting2");
|
||||||
settingEntity2.setEmail("test_setting2@test.com");
|
dynamicSettingAndMappingEntity2.setEmail("test_setting2@test.com");
|
||||||
|
|
||||||
repository.save(settingEntity2);
|
repository.save(dynamicSettingAndMappingEntity2);
|
||||||
|
|
||||||
//when
|
//when
|
||||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||||
.withQuery(QueryBuilders.termQuery("email", settingEntity1.getEmail())).build();
|
.withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build();
|
||||||
|
|
||||||
long count = elasticsearchTemplate.count(searchQuery, SettingEntity.class);
|
long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class);
|
||||||
List<SettingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery, SettingEntity.class);
|
List<DynamicSettingAndMappingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery, DynamicSettingAndMappingEntity.class);
|
||||||
|
|
||||||
//then
|
//then
|
||||||
assertThat(count, is(1L));
|
assertThat(count, is(1L));
|
||||||
assertThat(entityList, is(notNullValue()));
|
assertThat(entityList, is(notNullValue()));
|
||||||
assertThat(entityList.size(), is(1));
|
assertThat(entityList.size(), is(1));
|
||||||
assertThat(entityList.get(0).getEmail(), is(settingEntity1.getEmail()));
|
assertThat(entityList.get(0).getEmail(), is(dynamicSettingAndMappingEntity1.getEmail()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -115,7 +115,7 @@ public class SettingEntityRepositoryTest {
|
|||||||
//given
|
//given
|
||||||
//delete , create and apply mapping in before method
|
//delete , create and apply mapping in before method
|
||||||
//when
|
//when
|
||||||
Map mapping = elasticsearchTemplate.getMapping(SettingEntity.class);
|
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
|
||||||
//then
|
//then
|
||||||
Map properties = (Map) mapping.get("properties");
|
Map properties = (Map) mapping.get("properties");
|
||||||
assertThat(mapping, is(notNullValue()));
|
assertThat(mapping, is(notNullValue()));
|
||||||
@ -127,9 +127,9 @@ public class SettingEntityRepositoryTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateMappingWithSpecifiedMappings() {
|
public void shouldCreateMappingWithSpecifiedMappings() {
|
||||||
//given
|
//given
|
||||||
elasticsearchTemplate.deleteIndex(SettingEntity.class);
|
elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class);
|
||||||
elasticsearchTemplate.createIndex(SettingEntity.class);
|
elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class);
|
||||||
elasticsearchTemplate.refresh(SettingEntity.class, true);
|
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
|
||||||
//when
|
//when
|
||||||
String mappings = "{\n" +
|
String mappings = "{\n" +
|
||||||
" \"test-setting-type\" : {\n" +
|
" \"test-setting-type\" : {\n" +
|
||||||
@ -138,10 +138,26 @@ public class SettingEntityRepositoryTest {
|
|||||||
" }\n" +
|
" }\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
elasticsearchTemplate.putMapping(SettingEntity.class, mappings);
|
elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class, mappings);
|
||||||
elasticsearchTemplate.refresh(SettingEntity.class, true);
|
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
|
||||||
//then
|
//then
|
||||||
Map mapping = elasticsearchTemplate.getMapping(SettingEntity.class);
|
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
|
||||||
|
Map properties = (Map) mapping.get("properties");
|
||||||
|
assertThat(mapping, is(notNullValue()));
|
||||||
|
assertThat(properties, is(notNullValue()));
|
||||||
|
assertThat(((String) ((Map) properties.get("email")).get("type")), is("string"));
|
||||||
|
assertThat((String) ((Map)properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DATAES-86
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldCreateMappingWithUsingMappingAnnotation() {
|
||||||
|
//given
|
||||||
|
|
||||||
|
//then
|
||||||
|
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
|
||||||
Map properties = (Map) mapping.get("properties");
|
Map properties = (Map) mapping.get("properties");
|
||||||
assertThat(mapping, is(notNullValue()));
|
assertThat(mapping, is(notNullValue()));
|
||||||
assertThat(properties, is(notNullValue()));
|
assertThat(properties, is(notNullValue()));
|
7
src/test/resources/mappings/test-mappings.json
Normal file
7
src/test/resources/mappings/test-mappings.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"test-setting-type" : {
|
||||||
|
"properties" : {
|
||||||
|
"email" : {"type" : "string", "analyzer" : "emailAnalyzer" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user