Skip to content

Commit 6c5e8fe

Browse files
committed
Merge pull request #29 from javamachr/master
Added DefaultMapper support to map only partial fields from result instead of whole source field.
2 parents 30bd165 + 7b86505 commit 6c5e8fe

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

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

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,25 @@
1515
*/
1616
package org.springframework.data.elasticsearch.core;
1717

18+
1819
import org.elasticsearch.action.get.GetResponse;
1920
import org.elasticsearch.action.search.SearchResponse;
21+
import org.elasticsearch.common.base.Strings;
22+
import org.elasticsearch.common.jackson.core.JsonEncoding;
23+
import org.elasticsearch.common.jackson.core.JsonFactory;
24+
import org.elasticsearch.common.jackson.core.JsonGenerator;
2025
import org.elasticsearch.search.SearchHit;
26+
import org.elasticsearch.search.SearchHitField;
2127
import org.elasticsearch.search.facet.Facet;
2228
import org.springframework.data.domain.Pageable;
2329
import org.springframework.data.elasticsearch.core.facet.DefaultFacetMapper;
2430
import org.springframework.data.elasticsearch.core.facet.FacetResult;
2531

32+
import java.io.ByteArrayOutputStream;
33+
import java.io.IOException;
34+
import java.nio.charset.Charset;
2635
import java.util.ArrayList;
36+
import java.util.Collection;
2737
import java.util.List;
2838

2939
/**
@@ -45,7 +55,11 @@ public <T> FacetedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pa
4555
List<T> results = new ArrayList<T>();
4656
for (SearchHit hit : response.getHits()) {
4757
if (hit != null) {
48-
results.add(mapEntity(hit.sourceAsString(), clazz));
58+
if (!Strings.isNullOrEmpty(hit.sourceAsString())) {
59+
results.add(mapEntity(hit.sourceAsString(), clazz));
60+
} else {
61+
results.add(mapEntity(hit.getFields().values(), clazz));
62+
}
4963
}
5064
}
5165
List<FacetResult> facets = new ArrayList<FacetResult>();
@@ -61,6 +75,35 @@ public <T> FacetedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pa
6175
return new FacetedPageImpl<T>(results, pageable, totalHits, facets);
6276
}
6377

78+
private <T> T mapEntity(Collection<SearchHitField> values, Class<T> clazz) {
79+
return mapEntity(buildJSONFromFields(values), clazz);
80+
}
81+
82+
private String buildJSONFromFields(Collection<SearchHitField> values) {
83+
JsonFactory nodeFactory = new JsonFactory();
84+
try {
85+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
86+
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
87+
generator.writeStartObject();
88+
for (SearchHitField value : values) {
89+
if (value.getValues().size() > 1) {
90+
generator.writeArrayFieldStart(value.getName());
91+
for (Object val : value.getValues()) {
92+
generator.writeObject(val);
93+
}
94+
generator.writeEndArray();
95+
} else {
96+
generator.writeObjectField(value.getName(), value.getValue());
97+
}
98+
}
99+
generator.writeEndObject();
100+
generator.flush();
101+
return new String(stream.toByteArray(), Charset.forName("UTF-8"));
102+
} catch (IOException e) {
103+
return null;
104+
}
105+
}
106+
64107
@Override
65108
public <T> T mapResult(GetResponse response, Class<T> clazz) {
66109
return mapEntity(response.getSourceAsString(),clazz);

src/test/java/org/springframework/data/elasticsearch/core/DefaultResultMapperTests.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
import org.apache.commons.collections.iterators.ArrayIterator;
44
import org.elasticsearch.action.get.GetResponse;
55
import org.elasticsearch.action.search.SearchResponse;
6+
import org.elasticsearch.index.get.GetField;
67
import org.elasticsearch.search.SearchHit;
8+
import org.elasticsearch.search.SearchHitField;
79
import org.elasticsearch.search.SearchHits;
10+
import org.elasticsearch.search.internal.InternalSearchHitField;
811
import org.junit.Before;
912
import org.junit.Test;
1013
import org.mockito.Mock;
14+
import org.mockito.Mockito;
1115
import org.mockito.MockitoAnnotations;
1216
import org.springframework.data.elasticsearch.Car;
1317

18+
import java.util.Arrays;
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
1422
import static org.hamcrest.Matchers.is;
1523
import static org.hamcrest.Matchers.notNullValue;
1624
import static org.junit.Assert.assertThat;
@@ -51,6 +59,24 @@ public void shouldMapSearchRequestToPage() {
5159
assertThat(page.getContent().get(0).getName(), is("Ford"));
5260
}
5361

62+
@Test
63+
public void shouldMapPartialSearchRequestToObject() {
64+
//Given
65+
SearchHit[] hits = {createCarPartialHit("Ford", "Grat"), createCarPartialHit("BMW", "Arrow")};
66+
SearchHits searchHits = mock(SearchHits.class);
67+
when(searchHits.totalHits()).thenReturn(2L);
68+
when(searchHits.iterator()).thenReturn(new ArrayIterator(hits));
69+
when(response.getHits()).thenReturn(searchHits);
70+
71+
//When
72+
FacetedPage<Car> page = resultMapper.mapResults(response, Car.class, null);
73+
74+
//Then
75+
assertThat(page.hasContent(), is(true));
76+
assertThat(page.getTotalElements(), is(2L));
77+
assertThat(page.getContent().get(0).getName(), is("Ford"));
78+
}
79+
5480
@Test
5581
public void shouldMapGetRequestToObject() {
5682
//Given
@@ -72,6 +98,13 @@ private SearchHit createCarHit(String name, String model) {
7298
return hit;
7399
}
74100

101+
private SearchHit createCarPartialHit(String name, String model) {
102+
SearchHit hit = mock(SearchHit.class);
103+
when(hit.sourceAsString()).thenReturn(null);
104+
when(hit.getFields()).thenReturn(createCarFields(name, model));
105+
return hit;
106+
}
107+
75108
private String createJsonCar(String name, String model) {
76109
final String q = "\"";
77110
StringBuffer sb = new StringBuffer();
@@ -80,4 +113,11 @@ private String createJsonCar(String name, String model) {
80113
return sb.toString();
81114
}
82115

116+
private Map<String, SearchHitField> createCarFields(String name, String model) {
117+
Map<String, SearchHitField> result = new HashMap<String, SearchHitField>();
118+
result.put("name", new InternalSearchHitField("name", Arrays.<Object>asList(name)));
119+
result.put("model", new InternalSearchHitField("model", Arrays.<Object>asList(model)));
120+
return result;
121+
}
122+
83123
}

0 commit comments

Comments
 (0)