mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-22 20:12:11 +00:00
DATAES-77 - Search across different indices
Add test to demonstrate searching into heterogeneous indexes and building entities of different types. In a nutshall, the responsiblity lies with the client, spring data elasticsearch cannot and should not try to discover entity types, as that would leading building an object composition logic which is not the core area of this library. With this test, we demonstrate the usage of SearchResultMapper to compose an aggregator object that holds properties from two dfferent entities, The Aggregator is declared as a document but is not indexes (This is not ideal) and we don't recommend to declare @Documents that are not indexed. Please use this as just a pointer to implement SearchResultMapper, this demostartion is not meant to be duplicated in your production systems. There are better ways to compose hetro objects from multi index searches.
This commit is contained in:
parent
09e3e94b3b
commit
d24a92547f
@ -23,6 +23,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.elasticsearch.action.get.MultiGetItemResponse;
|
||||
import org.elasticsearch.action.get.MultiGetResponse;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
@ -35,13 +36,18 @@ import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.builder.SampleEntityBuilder;
|
||||
import org.springframework.data.elasticsearch.core.query.*;
|
||||
import org.springframework.data.elasticsearch.entities.HetroEntity1;
|
||||
import org.springframework.data.elasticsearch.entities.HetroEntity2;
|
||||
import org.springframework.data.elasticsearch.entities.SampleEntity;
|
||||
import org.springframework.data.elasticsearch.entities.SampleMappingEntity;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@ -74,8 +80,10 @@ public class ElasticsearchTemplateTests {
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
// @After
|
||||
/** // doing a cleanup to ensure that no indexes are left behind after the test run */
|
||||
/**
|
||||
public void after() {
|
||||
|
||||
// it is safe to call deleteIndex as it checks for index existance before deleting it
|
||||
@ -83,7 +91,7 @@ public class ElasticsearchTemplateTests {
|
||||
elasticsearchTemplate.deleteIndex(INDEX_1_NAME);
|
||||
elasticsearchTemplate.deleteIndex(INDEX_2_NAME);
|
||||
|
||||
}
|
||||
}**/
|
||||
|
||||
|
||||
@Test
|
||||
@ -706,7 +714,6 @@ public class ElasticsearchTemplateTests {
|
||||
@Test
|
||||
public void shouldReturnListForGivenStringQuery() {
|
||||
// given
|
||||
List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
|
||||
// first document
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity1 = new SampleEntityBuilder(documentId)
|
||||
@ -727,7 +734,7 @@ public class ElasticsearchTemplateTests {
|
||||
.rate(15)
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
|
||||
List<IndexQuery> indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.bulkIndex(indexQueries);
|
||||
@ -1556,6 +1563,47 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(sampleEntities.size(), is(equalTo(2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* This is basically a demonstration to show composing entities out of heterogeneous indexes.
|
||||
*/
|
||||
public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() {
|
||||
|
||||
// Given
|
||||
|
||||
HetroEntity1 entity1 = new HetroEntity1(randomNumeric(3), "aFirstName");
|
||||
HetroEntity2 entity2 = new HetroEntity2(randomNumeric(4), "aLastName");
|
||||
|
||||
IndexQuery idxQuery1 = new IndexQueryBuilder().withIndexName(INDEX_1_NAME).withId(entity1.getId()).withObject(entity1).build();
|
||||
IndexQuery idxQuery2 = new IndexQueryBuilder().withIndexName(INDEX_2_NAME).withId(entity2.getId()).withObject(entity2).build();
|
||||
|
||||
|
||||
elasticsearchTemplate.bulkIndex(Arrays.asList(idxQuery1, idxQuery2));
|
||||
elasticsearchTemplate.refresh(INDEX_1_NAME, true);
|
||||
elasticsearchTemplate.refresh(INDEX_2_NAME, true);
|
||||
|
||||
// When
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withTypes("hetro").withIndices(INDEX_1_NAME, INDEX_2_NAME).build();
|
||||
Page<ResultAggregator> page = elasticsearchTemplate.queryForPage(searchQuery, ResultAggregator.class, new SearchResultMapper() {
|
||||
@Override
|
||||
public <T> FacetedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
||||
List<ResultAggregator> values = new ArrayList<ResultAggregator>();
|
||||
for (SearchHit searchHit : response.getHits()) {
|
||||
String id = String.valueOf(searchHit.getSource().get("id"));
|
||||
String firstName = StringUtils.isNotEmpty((String)searchHit.getSource().get("firstName"))?(String)searchHit.getSource().get("firstName"):"";
|
||||
String lastName = StringUtils.isNotEmpty((String)searchHit.getSource().get("lastName"))?(String)searchHit.getSource().get("lastName"):"";
|
||||
values.add(new ResultAggregator(id, firstName, lastName));
|
||||
}
|
||||
return new FacetedPageImpl<T>((List<T>) values);
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(page.getTotalElements(), is(2l));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private IndexQuery getIndexQuery(SampleEntity sampleEntity) {
|
||||
return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build();
|
||||
}
|
||||
@ -1567,4 +1615,23 @@ public class ElasticsearchTemplateTests {
|
||||
}
|
||||
return indexQueries;
|
||||
}
|
||||
|
||||
@Document(indexName = INDEX_2_NAME, replicas = 0, shards = 1)
|
||||
class ResultAggregator {
|
||||
|
||||
private String id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
ResultAggregator(String id, String firstName, String lastName) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
package org.springframework.data.elasticsearch.entities;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
|
||||
/**
|
||||
* @author abdul.
|
||||
*/
|
||||
@Document(indexName = "test-index-1", type = "hetro", replicas = 0, shards = 1)
|
||||
public class HetroEntity1 {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
private String firstName;
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
public HetroEntity1(String id, String firstName) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.version = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public Long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof SampleEntity)) {
|
||||
return false;
|
||||
}
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
HetroEntity1 rhs = (HetroEntity1) obj;
|
||||
return new EqualsBuilder().append(this.id, rhs.id).append(this.firstName, rhs.firstName).append(this.version, rhs.version).isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder().append(id).append(firstName).append(version).toHashCode();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package org.springframework.data.elasticsearch.entities;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
|
||||
/**
|
||||
* @author abdul.
|
||||
*/
|
||||
@Document(indexName = "test-index-2", type = "hetro", replicas = 0, shards = 1)
|
||||
public class HetroEntity2 {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
private String lastName;
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
public HetroEntity2(String id, String lastName) {
|
||||
this.id = id;
|
||||
this.lastName = lastName;
|
||||
this.version = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public void setVersion(Long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public Long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof SampleEntity)) {
|
||||
return false;
|
||||
}
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
HetroEntity2 rhs = (HetroEntity2) obj;
|
||||
return new EqualsBuilder().append(this.id, rhs.id).append(this.lastName, rhs.lastName).append(this.version, rhs.version).isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder().append(id).append(lastName).append(version).toHashCode();
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user