DATAES-86 - Add dynamic mapping(json) using @Mapping annotation

This commit is contained in:
Mohsin Husen 2014-04-30 11:48:00 +01:00
parent 8c63f3ee22
commit 9ce87f147a
6 changed files with 108 additions and 42 deletions

View File

@ -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 "";
}

View File

@ -75,6 +75,7 @@ import org.springframework.data.domain.Page;
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.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
@ -138,6 +139,17 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
@Override
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);
XContentBuilder xContentBuilder = null;
try {

View File

@ -16,24 +16,21 @@
package org.springframework.data.elasticsearch.entities;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.annotations.*;
/**
* Sample SettingEntity for test out dynamic setting using @Setting Annotation
* Sample DynamicSettingAndMappingEntity for test out dynamic setting using @Setting Annotation
*
* @author Mohsin Husen
*/
@Setting(settingPath = "/settings/test-settings.json")
@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
private String id;
private String name;
@Field(type = FieldType.String, searchAnalyzer = "emailAnalyzer", indexAnalyzer = "emailAnalyzer")
private String email;
public String getId() {

View File

@ -15,14 +15,14 @@
*/
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;
/**
* SettingEntityRepository
* DynamicSettingAndMappingEntityRepository
*
* @author Mohsin Husen
*/
public interface SettingEntityRepository extends ElasticsearchCrudRepository<SettingEntity, String> {
public interface DynamicSettingAndMappingEntityRepository extends ElasticsearchCrudRepository<DynamicSettingAndMappingEntity, String> {
}

View File

@ -30,31 +30,31 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
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.junit4.SpringJUnit4ClassRunner;
/**
* SettingEntityRepositoryTest
* DynamicSettingAndMappingEntityRepositoryTests
*
* @author Mohsin Husen
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:dynamic-settings-test.xml")
public class SettingEntityRepositoryTest {
public class DynamicSettingAndMappingEntityRepositoryTests {
@Autowired
private SettingEntityRepository repository;
private DynamicSettingAndMappingEntityRepository repository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Before
public void before() {
elasticsearchTemplate.deleteIndex(SettingEntity.class);
elasticsearchTemplate.createIndex(SettingEntity.class);
elasticsearchTemplate.putMapping(SettingEntity.class);
elasticsearchTemplate.refresh(SettingEntity.class, true);
elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class);
elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class);
elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class);
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
}
/*
@ -66,8 +66,8 @@ public class SettingEntityRepositoryTest {
//delete , create and apply mapping in before method
// then
assertThat(elasticsearchTemplate.indexExists(SettingEntity.class), is(true));
Map map = elasticsearchTemplate.getSetting(SettingEntity.class);
assertThat(elasticsearchTemplate.indexExists(DynamicSettingAndMappingEntity.class), is(true));
Map map = elasticsearchTemplate.getSetting(DynamicSettingAndMappingEntity.class);
assertThat(map.containsKey("index.number_of_replicas"), is(true));
assertThat(map.containsKey("index.number_of_shards"), is(true));
assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer"), is(true));
@ -82,32 +82,32 @@ public class SettingEntityRepositoryTest {
@Test
public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() {
//given
SettingEntity settingEntity1 = new SettingEntity();
settingEntity1.setId(RandomStringUtils.randomNumeric(5));
settingEntity1.setName("test-setting1");
settingEntity1.setEmail("test_setting1@test.com");
DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity1 = new DynamicSettingAndMappingEntity();
dynamicSettingAndMappingEntity1.setId(RandomStringUtils.randomNumeric(5));
dynamicSettingAndMappingEntity1.setName("test-setting1");
dynamicSettingAndMappingEntity1.setEmail("test_setting1@test.com");
repository.save(settingEntity1);
repository.save(dynamicSettingAndMappingEntity1);
SettingEntity settingEntity2 = new SettingEntity();
settingEntity2.setId(RandomStringUtils.randomNumeric(5));
settingEntity2.setName("test-setting2");
settingEntity2.setEmail("test_setting2@test.com");
DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity2 = new DynamicSettingAndMappingEntity();
dynamicSettingAndMappingEntity2.setId(RandomStringUtils.randomNumeric(5));
dynamicSettingAndMappingEntity2.setName("test-setting2");
dynamicSettingAndMappingEntity2.setEmail("test_setting2@test.com");
repository.save(settingEntity2);
repository.save(dynamicSettingAndMappingEntity2);
//when
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);
List<SettingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery, SettingEntity.class);
long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class);
List<DynamicSettingAndMappingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery, DynamicSettingAndMappingEntity.class);
//then
assertThat(count, is(1L));
assertThat(entityList, is(notNullValue()));
assertThat(entityList.size(), is(1));
assertThat(entityList.get(0).getEmail(), is(settingEntity1.getEmail()));
assertThat(entityList.get(0).getEmail(), is(dynamicSettingAndMappingEntity1.getEmail()));
}
@Test
@ -115,7 +115,7 @@ public class SettingEntityRepositoryTest {
//given
//delete , create and apply mapping in before method
//when
Map mapping = elasticsearchTemplate.getMapping(SettingEntity.class);
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
//then
Map properties = (Map) mapping.get("properties");
assertThat(mapping, is(notNullValue()));
@ -127,9 +127,9 @@ public class SettingEntityRepositoryTest {
@Test
public void shouldCreateMappingWithSpecifiedMappings() {
//given
elasticsearchTemplate.deleteIndex(SettingEntity.class);
elasticsearchTemplate.createIndex(SettingEntity.class);
elasticsearchTemplate.refresh(SettingEntity.class, true);
elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class);
elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class);
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
//when
String mappings = "{\n" +
" \"test-setting-type\" : {\n" +
@ -138,10 +138,26 @@ public class SettingEntityRepositoryTest {
" }\n" +
" }\n" +
"}";
elasticsearchTemplate.putMapping(SettingEntity.class, mappings);
elasticsearchTemplate.refresh(SettingEntity.class, true);
elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class, mappings);
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
//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");
assertThat(mapping, is(notNullValue()));
assertThat(properties, is(notNullValue()));

View File

@ -0,0 +1,7 @@
{
"test-setting-type" : {
"properties" : {
"email" : {"type" : "string", "analyzer" : "emailAnalyzer" }
}
}
}