Skip to content

Commit 9ce87f1

Browse files
committed
DATAES-86 - Add dynamic mapping(json) using @mapping annotation
1 parent 8c63f3e commit 9ce87f1

File tree

6 files changed

+108
-42
lines changed

6 files changed

+108
-42
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.elasticsearch.annotations;
17+
18+
import java.lang.annotation.*;
19+
import org.springframework.data.annotation.Persistent;
20+
21+
/**
22+
* Elasticsearch Mapping
23+
*
24+
* @author Mohsin Husen
25+
*/
26+
@Persistent
27+
@Inherited
28+
@Retention(RetentionPolicy.RUNTIME)
29+
@Target({ElementType.TYPE})
30+
public @interface Mapping {
31+
32+
String mappingPath() default "";
33+
34+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import org.springframework.data.domain.Sort;
7676
import org.springframework.data.elasticsearch.ElasticsearchException;
7777
import org.springframework.data.elasticsearch.annotations.Document;
78+
import org.springframework.data.elasticsearch.annotations.Mapping;
7879
import org.springframework.data.elasticsearch.annotations.Setting;
7980
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
8081
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
@@ -138,6 +139,17 @@ public boolean createIndex(String indexName) {
138139

139140
@Override
140141
public <T> boolean putMapping(Class<T> clazz) {
142+
if (clazz.isAnnotationPresent(Mapping.class)) {
143+
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
144+
if (isNotBlank(mappingPath)) {
145+
String mappings = readFileFromClasspath(mappingPath);
146+
if (isNotBlank(mappings)) {
147+
return putMapping(clazz, mappings);
148+
}
149+
} else {
150+
logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
151+
}
152+
}
141153
ElasticsearchPersistentEntity<T> persistentEntity = getPersistentEntityFor(clazz);
142154
XContentBuilder xContentBuilder = null;
143155
try {

src/test/java/org/springframework/data/elasticsearch/entities/SettingEntity.java renamed to src/test/java/org/springframework/data/elasticsearch/entities/DynamicSettingAndMappingEntity.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,21 @@
1616
package org.springframework.data.elasticsearch.entities;
1717

1818
import org.springframework.data.annotation.Id;
19-
import org.springframework.data.elasticsearch.annotations.Document;
20-
import org.springframework.data.elasticsearch.annotations.Field;
21-
import org.springframework.data.elasticsearch.annotations.FieldType;
22-
import org.springframework.data.elasticsearch.annotations.Setting;
19+
import org.springframework.data.elasticsearch.annotations.*;
2320

2421
/**
25-
* Sample SettingEntity for test out dynamic setting using @Setting Annotation
22+
* Sample DynamicSettingAndMappingEntity for test out dynamic setting using @Setting Annotation
2623
*
2724
* @author Mohsin Husen
2825
*/
29-
@Setting(settingPath = "/settings/test-settings.json")
3026
@Document(indexName = "test-setting-index", type = "test-setting-type")
31-
public class SettingEntity {
27+
@Setting(settingPath = "/settings/test-settings.json")
28+
@Mapping(mappingPath = "/mappings/test-mappings.json")
29+
public class DynamicSettingAndMappingEntity {
3230

3331
@Id
3432
private String id;
3533
private String name;
36-
@Field(type = FieldType.String, searchAnalyzer = "emailAnalyzer", indexAnalyzer = "emailAnalyzer")
3734
private String email;
3835

3936
public String getId() {

src/test/java/org/springframework/data/elasticsearch/repositories/setting/SettingEntityRepository.java renamed to src/test/java/org/springframework/data/elasticsearch/repositories/setting/DynamicSettingAndMappingEntityRepository.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
*/
1616
package org.springframework.data.elasticsearch.repositories.setting;
1717

18-
import org.springframework.data.elasticsearch.entities.SettingEntity;
18+
import org.springframework.data.elasticsearch.entities.DynamicSettingAndMappingEntity;
1919
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
2020

2121
/**
22-
* SettingEntityRepository
22+
* DynamicSettingAndMappingEntityRepository
2323
*
2424
* @author Mohsin Husen
2525
*/
26-
public interface SettingEntityRepository extends ElasticsearchCrudRepository<SettingEntity, String> {
26+
public interface DynamicSettingAndMappingEntityRepository extends ElasticsearchCrudRepository<DynamicSettingAndMappingEntity, String> {
2727

2828
}

src/test/java/org/springframework/data/elasticsearch/repositories/setting/SettingEntityRepositoryTest.java renamed to src/test/java/org/springframework/data/elasticsearch/repositories/setting/DynamicSettingAndMappingEntityRepositoryTests.java

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,31 @@
3030
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
3131
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
3232
import org.springframework.data.elasticsearch.core.query.SearchQuery;
33-
import org.springframework.data.elasticsearch.entities.SettingEntity;
33+
import org.springframework.data.elasticsearch.entities.DynamicSettingAndMappingEntity;
3434
import org.springframework.test.context.ContextConfiguration;
3535
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
3636

3737
/**
38-
* SettingEntityRepositoryTest
38+
* DynamicSettingAndMappingEntityRepositoryTests
3939
*
4040
* @author Mohsin Husen
4141
*/
4242
@RunWith(SpringJUnit4ClassRunner.class)
4343
@ContextConfiguration("classpath:dynamic-settings-test.xml")
44-
public class SettingEntityRepositoryTest {
44+
public class DynamicSettingAndMappingEntityRepositoryTests {
4545

4646
@Autowired
47-
private SettingEntityRepository repository;
47+
private DynamicSettingAndMappingEntityRepository repository;
4848

4949
@Autowired
5050
private ElasticsearchTemplate elasticsearchTemplate;
5151

5252
@Before
5353
public void before() {
54-
elasticsearchTemplate.deleteIndex(SettingEntity.class);
55-
elasticsearchTemplate.createIndex(SettingEntity.class);
56-
elasticsearchTemplate.putMapping(SettingEntity.class);
57-
elasticsearchTemplate.refresh(SettingEntity.class, true);
54+
elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class);
55+
elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class);
56+
elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class);
57+
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
5858
}
5959

6060
/*
@@ -66,8 +66,8 @@ public void shouldCreateGivenDynamicSettingsForGivenIndex() {
6666
//delete , create and apply mapping in before method
6767

6868
// then
69-
assertThat(elasticsearchTemplate.indexExists(SettingEntity.class), is(true));
70-
Map map = elasticsearchTemplate.getSetting(SettingEntity.class);
69+
assertThat(elasticsearchTemplate.indexExists(DynamicSettingAndMappingEntity.class), is(true));
70+
Map map = elasticsearchTemplate.getSetting(DynamicSettingAndMappingEntity.class);
7171
assertThat(map.containsKey("index.number_of_replicas"), is(true));
7272
assertThat(map.containsKey("index.number_of_shards"), is(true));
7373
assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer"), is(true));
@@ -82,40 +82,40 @@ public void shouldCreateGivenDynamicSettingsForGivenIndex() {
8282
@Test
8383
public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() {
8484
//given
85-
SettingEntity settingEntity1 = new SettingEntity();
86-
settingEntity1.setId(RandomStringUtils.randomNumeric(5));
87-
settingEntity1.setName("test-setting1");
88-
settingEntity1.setEmail("[email protected]");
85+
DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity1 = new DynamicSettingAndMappingEntity();
86+
dynamicSettingAndMappingEntity1.setId(RandomStringUtils.randomNumeric(5));
87+
dynamicSettingAndMappingEntity1.setName("test-setting1");
88+
dynamicSettingAndMappingEntity1.setEmail("[email protected]");
8989

90-
repository.save(settingEntity1);
90+
repository.save(dynamicSettingAndMappingEntity1);
9191

92-
SettingEntity settingEntity2 = new SettingEntity();
93-
settingEntity2.setId(RandomStringUtils.randomNumeric(5));
94-
settingEntity2.setName("test-setting2");
95-
settingEntity2.setEmail("[email protected]");
92+
DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity2 = new DynamicSettingAndMappingEntity();
93+
dynamicSettingAndMappingEntity2.setId(RandomStringUtils.randomNumeric(5));
94+
dynamicSettingAndMappingEntity2.setName("test-setting2");
95+
dynamicSettingAndMappingEntity2.setEmail("[email protected]");
9696

97-
repository.save(settingEntity2);
97+
repository.save(dynamicSettingAndMappingEntity2);
9898

9999
//when
100100
SearchQuery searchQuery = new NativeSearchQueryBuilder()
101-
.withQuery(QueryBuilders.termQuery("email", settingEntity1.getEmail())).build();
101+
.withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build();
102102

103-
long count = elasticsearchTemplate.count(searchQuery, SettingEntity.class);
104-
List<SettingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery, SettingEntity.class);
103+
long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class);
104+
List<DynamicSettingAndMappingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery, DynamicSettingAndMappingEntity.class);
105105

106106
//then
107107
assertThat(count, is(1L));
108108
assertThat(entityList, is(notNullValue()));
109109
assertThat(entityList.size(), is(1));
110-
assertThat(entityList.get(0).getEmail(), is(settingEntity1.getEmail()));
110+
assertThat(entityList.get(0).getEmail(), is(dynamicSettingAndMappingEntity1.getEmail()));
111111
}
112112

113113
@Test
114114
public void shouldGetMappingForGivenIndexAndType() {
115115
//given
116116
//delete , create and apply mapping in before method
117117
//when
118-
Map mapping = elasticsearchTemplate.getMapping(SettingEntity.class);
118+
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
119119
//then
120120
Map properties = (Map) mapping.get("properties");
121121
assertThat(mapping, is(notNullValue()));
@@ -127,9 +127,9 @@ public void shouldGetMappingForGivenIndexAndType() {
127127
@Test
128128
public void shouldCreateMappingWithSpecifiedMappings() {
129129
//given
130-
elasticsearchTemplate.deleteIndex(SettingEntity.class);
131-
elasticsearchTemplate.createIndex(SettingEntity.class);
132-
elasticsearchTemplate.refresh(SettingEntity.class, true);
130+
elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class);
131+
elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class);
132+
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
133133
//when
134134
String mappings = "{\n" +
135135
" \"test-setting-type\" : {\n" +
@@ -138,10 +138,26 @@ public void shouldCreateMappingWithSpecifiedMappings() {
138138
" }\n" +
139139
" }\n" +
140140
"}";
141-
elasticsearchTemplate.putMapping(SettingEntity.class, mappings);
142-
elasticsearchTemplate.refresh(SettingEntity.class, true);
141+
elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class, mappings);
142+
elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class, true);
143143
//then
144-
Map mapping = elasticsearchTemplate.getMapping(SettingEntity.class);
144+
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
145+
Map properties = (Map) mapping.get("properties");
146+
assertThat(mapping, is(notNullValue()));
147+
assertThat(properties, is(notNullValue()));
148+
assertThat(((String) ((Map) properties.get("email")).get("type")), is("string"));
149+
assertThat((String) ((Map)properties.get("email")).get("analyzer"), is("emailAnalyzer"));
150+
}
151+
152+
/*
153+
DATAES-86
154+
*/
155+
@Test
156+
public void shouldCreateMappingWithUsingMappingAnnotation() {
157+
//given
158+
159+
//then
160+
Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class);
145161
Map properties = (Map) mapping.get("properties");
146162
assertThat(mapping, is(notNullValue()));
147163
assertThat(properties, is(notNullValue()));
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"test-setting-type" : {
3+
"properties" : {
4+
"email" : {"type" : "string", "analyzer" : "emailAnalyzer" }
5+
}
6+
}
7+
}

0 commit comments

Comments
 (0)