diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java index 399e3565b..2f69a712c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultResultMapper.java @@ -22,9 +22,12 @@ import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedList; import java.util.List; import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.MultiGetItemResponse; +import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.base.Strings; import org.elasticsearch.common.jackson.core.JsonEncoding; @@ -129,6 +132,18 @@ public class DefaultResultMapper extends AbstractResultMapper { return result; } + @Override + public LinkedList mapResults(MultiGetResponse responses, Class clazz) { + LinkedList list = new LinkedList(); + for (MultiGetItemResponse response : responses.getResponses()) { + if (!response.isFailed() && response.getResponse().isExists()) { + T result = mapEntity(response.getResponse().getSourceAsString(), clazz); + list.add(result); + } + } + return list; + } + private void setPersistentEntityId(T result, String id, Class clazz) { if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) { PersistentProperty idProperty = mappingContext.getPersistentEntity(clazz).getIdProperty(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index b897799e4..ac581b959 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -183,7 +183,7 @@ public interface ElasticsearchOperations { long count(SearchQuery query, Class clazz); /** - * Execute a multiget against elasticsearch for the given ids + * Execute a multiGet against elasticsearch for the given ids * * @param searchQuery * @param clazz @@ -191,6 +191,16 @@ public interface ElasticsearchOperations { */ LinkedList multiGet(SearchQuery searchQuery, Class clazz); + /** + * Execute a multiGet against elasticsearch for the given ids with MultiGetResultMapper + * + * @param searchQuery + * @param clazz + * @param multiGetResultMapper + * @return + */ + LinkedList multiGet(SearchQuery searchQuery, Class clazz, MultiGetResultMapper multiGetResultMapper); + /** * Index an object. Will do save or update * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index b23167db0..98d1308f3 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -37,7 +37,10 @@ import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.count.CountRequestBuilder; -import org.elasticsearch.action.get.*; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.MultiGetRequest; +import org.elasticsearch.action.get.MultiGetRequestBuilder; +import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.mlt.MoreLikeThisRequestBuilder; import org.elasticsearch.action.search.SearchRequestBuilder; @@ -248,6 +251,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations { @Override public LinkedList multiGet(SearchQuery searchQuery, Class clazz) { + return resultsMapper.mapResults(getMultiResponse(searchQuery, clazz), clazz); + } + + private MultiGetResponse getMultiResponse(SearchQuery searchQuery, Class clazz) { ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); @@ -266,14 +273,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations { } builder.add(item); } - MultiGetResponse responses = builder.execute().actionGet(); - final LinkedList result = new LinkedList(); - for (MultiGetItemResponse response : responses.getResponses()) { - if (!response.isFailed() && response.getResponse().isExists()) { - result.add(resultsMapper.mapResult(response.getResponse(), clazz)); - } - } - return result; + return builder.execute().actionGet(); + } + + @Override + public LinkedList multiGet(SearchQuery searchQuery, Class clazz, MultiGetResultMapper getResultMapper) { + return getResultMapper.mapResults(getMultiResponse(searchQuery, clazz), clazz); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/MultiGetResultMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/MultiGetResultMapper.java new file mode 100644 index 000000000..c5169ed7e --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/MultiGetResultMapper.java @@ -0,0 +1,29 @@ +/* + * 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.core; + +import java.util.LinkedList; + +import org.elasticsearch.action.get.MultiGetResponse; + +/** + * @author Mohsin Husen + */ +public interface MultiGetResultMapper { + + LinkedList mapResults(MultiGetResponse responses, Class clazz); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ResultsMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/ResultsMapper.java index 27d4ea8ab..bd87082b6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ResultsMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ResultsMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-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. @@ -23,7 +23,7 @@ package org.springframework.data.elasticsearch.core; * @author Artur Konczak */ -public interface ResultsMapper extends SearchResultMapper, GetResultMapper { +public interface ResultsMapper extends SearchResultMapper, GetResultMapper, MultiGetResultMapper { EntityMapper getEntityMapper(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CustomResultMapper.java b/src/test/java/org/springframework/data/elasticsearch/core/CustomResultMapper.java index ccd7d10c9..02f9eb5bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CustomResultMapper.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CustomResultMapper.java @@ -15,7 +15,10 @@ */ package org.springframework.data.elasticsearch.core; +import java.util.LinkedList; + import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.search.SearchResponse; import org.springframework.data.domain.Pageable; @@ -46,4 +49,9 @@ public class CustomResultMapper implements ResultsMapper { public FacetedPage mapResults(SearchResponse response, Class clazz, Pageable pageable) { return null; //To change body of implemented methods use File | Settings | File Templates. } + + @Override + public LinkedList mapResults(MultiGetResponse responses, Class clazz) { + return null; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index b5257c174..a2730fd81 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -23,6 +23,8 @@ import static org.junit.Assert.*; import java.util.*; +import org.elasticsearch.action.get.MultiGetItemResponse; +import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.engine.DocumentMissingException; @@ -153,6 +155,63 @@ public class ElasticsearchTemplateTests { assertEquals(sampleEntities.get(1), sampleEntity2); } + @Test + public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { + // given + List indexQueries = new ArrayList(); + // first document + String documentId = randomNumeric(5); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(documentId); + sampleEntity1.setMessage("some message"); + sampleEntity1.setType("type1"); + sampleEntity1.setVersion(System.currentTimeMillis()); + + IndexQuery indexQuery1 = new IndexQuery(); + indexQuery1.setId(documentId); + indexQuery1.setObject(sampleEntity1); + indexQueries.add(indexQuery1); + + // second document + String documentId2 = randomNumeric(5); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + sampleEntity2.setMessage("some message"); + sampleEntity2.setType("type2"); + sampleEntity2.setVersion(System.currentTimeMillis()); + + IndexQuery indexQuery2 = new IndexQuery(); + indexQuery2.setId(documentId2); + indexQuery2.setObject(sampleEntity2); + + indexQueries.add(indexQuery2); + + elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.refresh(SampleEntity.class, true); + + // when + SearchQuery query = new NativeSearchQueryBuilder() + .withIds(Arrays.asList(documentId, documentId2)) + .withFields("message", "type") + .build(); + LinkedList sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class, new MultiGetResultMapper() { + @Override + public LinkedList mapResults(MultiGetResponse responses, Class clazz) { + LinkedList list = new LinkedList(); + for (MultiGetItemResponse response : responses.getResponses()) { + SampleEntity entity = new SampleEntity(); + entity.setId(response.getResponse().getId()); + entity.setMessage((String) response.getResponse().getField("message").getValue()); + entity.setType((String) response.getResponse().getField("type").getValue()); + list.add((T) entity); + } + return list; + } + }); + // then + assertThat(sampleEntities.size(), is(equalTo(2))); + } + @Test public void shouldReturnPageForGivenSearchQuery() { // given