diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java index 7a128ae11..e17c42933 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -23,8 +23,7 @@ import java.util.Map; import java.util.stream.Collectors; import org.elasticsearch.search.aggregations.Aggregations; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.NestedMetaData; @@ -43,12 +42,11 @@ import org.springframework.util.Assert; * @author Peter-Josef Meisch * @author Mark Paluch * @author Roman Puchkovskiy + * @author Sascha Woo * @since 4.0 */ class SearchHitMapping { - private static final Logger LOGGER = LoggerFactory.getLogger(SearchHitMapping.class); - private final Class type; private final ElasticsearchConverter converter; private final MappingContext, ElasticsearchPersistentProperty> mappingContext; @@ -169,7 +167,7 @@ class SearchHitMapping { */ private SearchHits mapInnerDocuments(SearchHits searchHits, Class type) { - if (searchHits.getTotalHits() == 0) { + if (searchHits.isEmpty()) { return searchHits; } @@ -210,7 +208,7 @@ class SearchHitMapping { searchHits.getAggregations()); } } catch (Exception e) { - LOGGER.warn("Could not map inner_hits", e); + throw new UncategorizedElasticsearchException("Unable to convert inner hits.", e); } return searchHits; 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 8de3a1d3c..8804963ae 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -53,6 +53,10 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.index.VersionType; +import org.elasticsearch.index.query.InnerHitBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.join.query.HasChildQueryBuilder; +import org.elasticsearch.join.query.JoinQueryBuilders; import org.elasticsearch.join.query.ParentIdQueryBuilder; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; @@ -2988,6 +2992,46 @@ public abstract class ElasticsearchTemplateTests { indexOperations.removeAlias(aliasQuery); } + @Test // #1997 + @DisplayName("should return document with inner hits size zero") + void shouldReturnDocumentWithInnerHitsSizeZero() { + + // given + SampleJoinEntity sampleQuestionEntity1 = new SampleJoinEntity(); + sampleQuestionEntity1.setUuid("q1"); + sampleQuestionEntity1.setText("This is a question"); + sampleQuestionEntity1.setMyJoinField(new JoinField<>("question")); + + SampleJoinEntity sampleAnswerEntity1 = new SampleJoinEntity(); + sampleAnswerEntity1.setUuid("a1"); + sampleAnswerEntity1.setText("This is an answer"); + sampleAnswerEntity1.setMyJoinField(new JoinField<>("answer", sampleQuestionEntity1.getUuid())); + + SampleJoinEntity sampleAnswerEntity2 = new SampleJoinEntity(); + sampleAnswerEntity1.setUuid("a2"); + sampleAnswerEntity1.setText("This is an answer"); + sampleAnswerEntity1.setMyJoinField(new JoinField<>("answer", sampleQuestionEntity1.getUuid())); + + IndexOperations indexOps = operations.indexOps(SampleJoinEntity.class); + operations.save(Arrays.asList(sampleQuestionEntity1, sampleAnswerEntity1, sampleAnswerEntity2)); + indexOps.refresh(); + + // when + Query query = new NativeSearchQueryBuilder().withQuery( + JoinQueryBuilders.hasChildQuery("answer", matchAllQuery(), org.apache.lucene.search.join.ScoreMode.Avg) + .innerHit(new InnerHitBuilder("innerHits").setSize(0))) + .build(); + + SearchHits searchHits = operations.search(query, SampleJoinEntity.class); + + // then + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHits()).hasSize(1); + assertThat(searchHits.getSearchHit(0).getInnerHits().size()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getInnerHits("innerHits").getTotalHits()).isEqualTo(1); + } + @Test // DATAES-541 public void shouldRemoveAlias() {