DATAES-37 : Multiple level Nested Document support

This commit is contained in:
mohsin.husen
2014-01-04 11:54:56 +00:00
parent 41fe0bed42
commit bc1abd96e8
6 changed files with 288 additions and 27 deletions

View File

@@ -0,0 +1,59 @@
/*
* 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;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.List;
/**
* @author Mohsin Husen
*/
public class GirlFriend {
private String name;
private String type;
@Field(type = FieldType.Nested)
private List<Car> cars;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
}

View File

@@ -15,12 +15,15 @@
*/
package org.springframework.data.elasticsearch;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
@@ -67,10 +70,14 @@ public class NestedObjectTests {
elasticsearchTemplate.createIndex(Person.class);
elasticsearchTemplate.putMapping(Person.class);
elasticsearchTemplate.refresh(Person.class, true);
elasticsearchTemplate.deleteIndex(PersonMultipleLevelNested.class);
elasticsearchTemplate.createIndex(PersonMultipleLevelNested.class);
elasticsearchTemplate.putMapping(PersonMultipleLevelNested.class);
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class,true);
}
@Test
public void shouldIndexNestedObject(){
public void shouldIndexInitialLevelNestedObject(){
List<Car> cars = new ArrayList<Car>();
@@ -128,6 +135,48 @@ public class NestedObjectTests {
assertThat(persons.size() , is(1));
}
@Test
public void shouldIndexMultipleLevelNestedObject(){
//given
List<IndexQuery> indexQueries = createPerson();
//when
elasticsearchTemplate.putMapping(PersonMultipleLevelNested.class);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class, true);
//then
GetQuery getQuery = new GetQuery();
getQuery.setId("1");
PersonMultipleLevelNested personIndexed = elasticsearchTemplate.queryForObject(getQuery, PersonMultipleLevelNested.class);
assertThat(personIndexed, is(notNullValue()));
}
@Test
public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject(){
//given
List<IndexQuery> indexQueries = createPerson();
//when
elasticsearchTemplate.putMapping(PersonMultipleLevelNested.class);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class, true);
//then
BoolQueryBuilder builder = boolQuery();
builder.must(nestedQuery("girlFriends", termQuery("girlFriends.type","temp")))
.must(nestedQuery("girlFriends.cars", termQuery("girlFriends.cars.name", "Ford".toLowerCase())));
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(builder)
.build();
Page<PersonMultipleLevelNested> personIndexed = elasticsearchTemplate.queryForPage(searchQuery, PersonMultipleLevelNested.class);
assertThat(personIndexed, is(notNullValue()));
assertThat(personIndexed.getTotalElements(), is(1L));
assertThat(personIndexed.getContent().get(0).getId(), is("1"));
}
@Test
@@ -146,4 +195,63 @@ public class NestedObjectTests {
// then
assertThat(bookRepository.findOne(id), is(notNullValue()));
}
private List<IndexQuery> createPerson(){
PersonMultipleLevelNested person1 = new PersonMultipleLevelNested();
person1.setId("1");
person1.setName("name");
Car saturn = new Car();
saturn.setName("Saturn");
saturn.setModel("SL");
Car subaru = new Car();
subaru.setName("Subaru");
subaru.setModel("Imprezza");
Car car = new Car();
car.setName("Saturn");
car.setModel("Imprezza");
Car ford = new Car();
ford.setName("Ford");
ford.setModel("Focus");
GirlFriend permanent = new GirlFriend();
permanent.setName("permanent");
permanent.setType("permanent");
permanent.setCars(Arrays.asList(saturn, subaru));
GirlFriend temp = new GirlFriend();
temp.setName("temp");
temp.setType("temp");
temp.setCars(Arrays.asList(car,ford));
person1.setGirlFriends(Arrays.asList(permanent, temp));
IndexQuery indexQuery1 = new IndexQuery();
indexQuery1.setId(person1.getId());
indexQuery1.setObject(person1);
PersonMultipleLevelNested person2 = new PersonMultipleLevelNested();
person2.setId("2");
person2.setName("name");
person2.setGirlFriends(Arrays.asList(permanent));
IndexQuery indexQuery2 = new IndexQuery();
indexQuery2.setId(person2.getId());
indexQuery2.setObject(person2);
List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
indexQueries.add(indexQuery1);
indexQueries.add(indexQuery2);
return indexQueries;
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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;
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 java.util.List;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
*/
@Document( indexName = "person-multiple-level-nested" , type = "user", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1")
public class PersonMultipleLevelNested {
@Id
private String id;
private String name;
@Field(type = FieldType.Nested)
private List<GirlFriend> girlFriends;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<GirlFriend> getGirlFriends() {
return girlFriends;
}
public void setGirlFriends(List<GirlFriend> girlFriends) {
this.girlFriends = girlFriends;
}
}

View File

@@ -869,7 +869,7 @@ public class ElasticsearchTemplateTests {
indexQuery.setObject(sampleEntity);
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.refresh(SampleEntity.class, true);
// when
elasticsearchTemplate.deleteType("test-index", "test-type");

View File

@@ -4,8 +4,10 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.*;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.SampleTransientEntity;
import org.springframework.data.elasticsearch.SimpleRecursiveEntity;
import org.springframework.data.elasticsearch.StockPrice;
import org.springframework.data.elasticsearch.StockPriceBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.ContextConfiguration;
@@ -18,8 +20,6 @@ import java.util.List;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
/**
* @author Stuart Stevenson