Skip to content

Commit d92f415

Browse files
committed
DATAES-48 - Mapping for multiple level nested document is getting created wrong
1 parent e9a2602 commit d92f415

File tree

6 files changed

+184
-34
lines changed

6 files changed

+184
-34
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 the original author or authors.
2+
* Copyright 2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -67,20 +67,20 @@ static XContentBuilder buildMapping(Class clazz, String indexType, String idFiel
6767
// Properties
6868
XContentBuilder xContentBuilder = mapping.startObject(FIELD_PROPERTIES);
6969

70-
mapEntity(xContentBuilder, clazz, true, idFieldName, EMPTY, false);
70+
mapEntity(xContentBuilder, clazz, true, idFieldName, EMPTY, false, FieldType.Auto);
7171

7272
return xContentBuilder.endObject().endObject().endObject();
7373
}
7474

7575
private static void mapEntity(XContentBuilder xContentBuilder, Class clazz, boolean isRootObject, String idFieldName,
76-
String nestedObjectFieldName, boolean nestedAnnotaion) throws IOException {
76+
String nestedObjectFieldName, boolean nestedOrObjectField, FieldType fieldType) throws IOException {
7777

7878
java.lang.reflect.Field[] fields = clazz.getDeclaredFields();
7979

80-
if (!isRootObject && (isAnyPropertyAnnotatedAsField(fields) || nestedAnnotaion)) {
80+
if (!isRootObject && (isAnyPropertyAnnotatedAsField(fields) || nestedOrObjectField)) {
8181
String type = FieldType.Object.toString().toLowerCase();
82-
if (nestedAnnotaion) {
83-
type = FieldType.Nested.toString().toLowerCase();
82+
if (nestedOrObjectField) {
83+
type = fieldType.toString().toLowerCase();
8484
}
8585
xContentBuilder.startObject(nestedObjectFieldName).field(FIELD_TYPE, type).startObject(FIELD_PROPERTIES);
8686
}
@@ -98,9 +98,9 @@ private static void mapEntity(XContentBuilder xContentBuilder, Class clazz, bool
9898
if (singleField == null) {
9999
continue;
100100
}
101-
boolean nestedField = isNestedField(field);
102-
mapEntity(xContentBuilder, getFieldType(field), false, EMPTY, field.getName(), nestedField);
103-
if (nestedField) {
101+
boolean nestedOrObject = isNestedOrObjectField(field);
102+
mapEntity(xContentBuilder, getFieldType(field), false, EMPTY, field.getName(), nestedOrObject, field.getAnnotation(Field.class).type());
103+
if (nestedOrObject) {
104104
continue;
105105
}
106106
}
@@ -120,7 +120,7 @@ private static void mapEntity(XContentBuilder xContentBuilder, Class clazz, bool
120120
}
121121
}
122122

123-
if (!isRootObject && isAnyPropertyAnnotatedAsField(fields)) {
123+
if (!isRootObject && isAnyPropertyAnnotatedAsField(fields) || nestedOrObjectField) {
124124
xContentBuilder.endObject().endObject();
125125
}
126126
}
@@ -296,7 +296,7 @@ private static boolean isInIgnoreFields(java.lang.reflect.Field field) {
296296
return false;
297297
}
298298

299-
private static boolean isNestedField(java.lang.reflect.Field field) {
299+
private static boolean isNestedOrObjectField(java.lang.reflect.Field field) {
300300
Field fieldAnnotation = field.getAnnotation(Field.class);
301301
return fieldAnnotation != null && (FieldType.Nested == fieldAnnotation.type() || FieldType.Object == fieldAnnotation.type());
302302
}

src/test/java/org/springframework/data/elasticsearch/Book.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 the original author or authors.
2+
* Copyright 2013-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
1717

1818
import org.springframework.data.annotation.Id;
1919
import org.springframework.data.elasticsearch.annotations.Document;
20+
import org.springframework.data.elasticsearch.annotations.Field;
21+
import org.springframework.data.elasticsearch.annotations.FieldType;
2022

2123
/**
2224
* @author Rizwan Idrees
@@ -28,6 +30,7 @@ public class Book {
2830
@Id
2931
private String id;
3032
private String name;
33+
@Field(type = FieldType.Object)
3134
private Author author;
3235

3336
public String getId() {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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+
17+
package org.springframework.data.elasticsearch;
18+
19+
import static org.apache.commons.lang.RandomStringUtils.*;
20+
import static org.hamcrest.Matchers.*;
21+
import static org.junit.Assert.*;
22+
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
import org.springframework.beans.factory.annotation.Autowired;
27+
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
28+
import org.springframework.data.elasticsearch.repositories.SampleElasticSearchBookRepository;
29+
import org.springframework.test.context.ContextConfiguration;
30+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
31+
32+
/**
33+
* @author Mohsin Husen
34+
*/
35+
36+
@RunWith(SpringJUnit4ClassRunner.class)
37+
@ContextConfiguration("classpath:/repository-test-nested-object.xml")
38+
public class InnerObjectTests {
39+
40+
@Autowired
41+
private SampleElasticSearchBookRepository bookRepository;
42+
43+
@Autowired
44+
private ElasticsearchTemplate elasticsearchTemplate;
45+
46+
@Before
47+
public void before() {
48+
elasticsearchTemplate.deleteIndex(Book.class);
49+
elasticsearchTemplate.createIndex(Book.class);
50+
elasticsearchTemplate.refresh(Book.class, true);
51+
}
52+
53+
@Test
54+
public void shouldIndexInnerObject() {
55+
// given
56+
String id = randomAlphanumeric(5);
57+
Book book = new Book();
58+
book.setId(id);
59+
book.setName("xyz");
60+
Author author = new Author();
61+
author.setId("1");
62+
author.setName("ABC");
63+
book.setAuthor(author);
64+
// when
65+
bookRepository.save(book);
66+
// then
67+
assertThat(bookRepository.findOne(id), is(notNullValue()));
68+
}
69+
}

src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.springframework.data.elasticsearch;
1717

18-
import static org.apache.commons.lang.RandomStringUtils.*;
1918
import static org.elasticsearch.index.query.QueryBuilders.*;
2019
import static org.hamcrest.Matchers.*;
2120
import static org.junit.Assert.*;
@@ -36,7 +35,6 @@
3635
import org.springframework.data.elasticsearch.core.query.IndexQuery;
3736
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
3837
import org.springframework.data.elasticsearch.core.query.SearchQuery;
39-
import org.springframework.data.elasticsearch.repositories.SampleElasticSearchBookRepository;
4038
import org.springframework.test.context.ContextConfiguration;
4139
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
4240

@@ -49,9 +47,6 @@
4947
@ContextConfiguration("classpath:/repository-test-nested-object.xml")
5048
public class NestedObjectTests {
5149

52-
@Autowired
53-
private SampleElasticSearchBookRepository bookRepository;
54-
5550
@Autowired
5651
private ElasticsearchTemplate elasticsearchTemplate;
5752

@@ -172,22 +167,6 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() {
172167
assertThat(personIndexed.getContent().get(0).getId(), is("1"));
173168
}
174169

175-
@Test
176-
public void shouldIndexInnerObject() {
177-
// given
178-
String id = randomAlphanumeric(5);
179-
Book book = new Book();
180-
book.setId(id);
181-
book.setName("xyz");
182-
Author author = new Author();
183-
author.setId("1");
184-
author.setName("ABC");
185-
book.setAuthor(author);
186-
// when
187-
bookRepository.save(book);
188-
// then
189-
assertThat(bookRepository.findOne(id), is(notNullValue()));
190-
}
191170

192171
private List<IndexQuery> createPerson() {
193172

@@ -245,4 +224,81 @@ private List<IndexQuery> createPerson() {
245224

246225
return indexQueries;
247226
}
227+
228+
@Test
229+
public void shouldSearchBooksForPersonInitialLevelNestedType() {
230+
231+
List<Car> cars = new ArrayList<Car>();
232+
233+
Car saturn = new Car();
234+
saturn.setName("Saturn");
235+
saturn.setModel("SL");
236+
237+
Car subaru = new Car();
238+
subaru.setName("Subaru");
239+
subaru.setModel("Imprezza");
240+
241+
Car ford = new Car();
242+
ford.setName("Ford");
243+
ford.setModel("Focus");
244+
245+
cars.add(saturn);
246+
cars.add(subaru);
247+
cars.add(ford);
248+
249+
Book java = new Book();
250+
java.setId("1");
251+
java.setName("java");
252+
Author javaAuthor = new Author();
253+
javaAuthor.setId("1");
254+
javaAuthor.setName("javaAuthor");
255+
java.setAuthor(javaAuthor);
256+
257+
Book spring= new Book();
258+
spring.setId("2");
259+
spring.setName("spring");
260+
Author springAuthor = new Author();
261+
springAuthor.setId("2");
262+
springAuthor.setName("springAuthor");
263+
spring.setAuthor(springAuthor);
264+
265+
Person foo = new Person();
266+
foo.setName("Foo");
267+
foo.setId("1");
268+
foo.setCar(cars);
269+
foo.setBooks(Arrays.asList(java, spring));
270+
271+
Car car = new Car();
272+
car.setName("Saturn");
273+
car.setModel("Imprezza");
274+
275+
Person bar = new Person();
276+
bar.setId("2");
277+
bar.setName("Bar");
278+
bar.setCar(Arrays.asList(car));
279+
280+
List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
281+
IndexQuery indexQuery1 = new IndexQuery();
282+
indexQuery1.setId(foo.getId());
283+
indexQuery1.setObject(foo);
284+
285+
IndexQuery indexQuery2 = new IndexQuery();
286+
indexQuery2.setId(bar.getId());
287+
indexQuery2.setObject(bar);
288+
289+
indexQueries.add(indexQuery1);
290+
indexQueries.add(indexQuery2);
291+
292+
elasticsearchTemplate.putMapping(Person.class);
293+
elasticsearchTemplate.bulkIndex(indexQueries);
294+
elasticsearchTemplate.refresh(Person.class, true);
295+
296+
QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")));
297+
298+
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
299+
List<Person> persons = elasticsearchTemplate.queryForList(searchQuery, Person.class);
300+
301+
assertThat(persons.size(), is(1));
302+
303+
}
248304
}

src/test/java/org/springframework/data/elasticsearch/Person.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 the original author or authors.
2+
* Copyright 2013-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,6 +40,9 @@ public class Person {
4040
@Field(type = FieldType.Nested)
4141
private List<Car> car;
4242

43+
@Field(type = FieldType.Nested)
44+
private List<Book> books;
45+
4346
public String getId() {
4447
return id;
4548
}
@@ -63,4 +66,12 @@ public List<Car> getCar() {
6366
public void setCar(List<Car> car) {
6467
this.car = car;
6568
}
69+
70+
public List<Book> getBooks() {
71+
return books;
72+
}
73+
74+
public void setBooks(List<Book> books) {
75+
this.books = books;
76+
}
6677
}

src/test/java/org/springframework/data/elasticsearch/PersonMultipleLevelNested.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public class PersonMultipleLevelNested {
4040
@Field(type = FieldType.Nested)
4141
private List<GirlFriend> girlFriends;
4242

43+
@Field(type = FieldType.Nested)
44+
private List<Car> cars;
45+
4346
public String getId() {
4447
return id;
4548
}
@@ -63,4 +66,12 @@ public List<GirlFriend> getGirlFriends() {
6366
public void setGirlFriends(List<GirlFriend> girlFriends) {
6467
this.girlFriends = girlFriends;
6568
}
69+
70+
public List<Car> getCars() {
71+
return cars;
72+
}
73+
74+
public void setCars(List<Car> cars) {
75+
this.cars = cars;
76+
}
6677
}

0 commit comments

Comments
 (0)