diff --git a/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java index 09184ecda0a87..8892a69f2dfc1 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java @@ -284,7 +284,7 @@ private SearchHit createNestedSearchHit(SearchContext context, int nestedTopDocI } context.lookup().source().setSource(nestedSourceAsMap); XContentType contentType = tuple.v1(); - BytesReference nestedSource = contentBuilder(contentType).map(sourceAsMap).bytes(); + BytesReference nestedSource = contentBuilder(contentType).map(nestedSourceAsMap).bytes(); context.lookup().source().setSource(nestedSource); context.lookup().source().setSourceContentType(contentType); } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java index 2287d2ba9864a..d1283c06ed273 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java @@ -28,7 +28,6 @@ import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.plugins.Plugin; @@ -67,6 +66,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.nestedQuery; @@ -728,7 +728,7 @@ public void testTopHitsInNestedSimple() throws Exception { assertThat(searchHits.getTotalHits(), equalTo(1L)); assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(0).getNestedIdentity().getOffset(), equalTo(0)); - assertThat((Integer) searchHits.getAt(0).getSourceAsMap().get("date"), equalTo(1)); + assertThat(extractValue("comments.date", searchHits.getAt(0).getSourceAsMap()), equalTo(1)); bucket = terms.getBucketByKey("b"); assertThat(bucket.getDocCount(), equalTo(2L)); @@ -737,10 +737,10 @@ public void testTopHitsInNestedSimple() throws Exception { assertThat(searchHits.getTotalHits(), equalTo(2L)); assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(0).getNestedIdentity().getOffset(), equalTo(1)); - assertThat((Integer) searchHits.getAt(0).getSourceAsMap().get("date"), equalTo(2)); + assertThat(extractValue("comments.date", searchHits.getAt(0).getSourceAsMap()), equalTo(2)); assertThat(searchHits.getAt(1).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(1).getNestedIdentity().getOffset(), equalTo(0)); - assertThat((Integer) searchHits.getAt(1).getSourceAsMap().get("date"), equalTo(3)); + assertThat(extractValue("comments.date", searchHits.getAt(1).getSourceAsMap()), equalTo(3)); bucket = terms.getBucketByKey("c"); assertThat(bucket.getDocCount(), equalTo(1L)); @@ -749,7 +749,7 @@ public void testTopHitsInNestedSimple() throws Exception { assertThat(searchHits.getTotalHits(), equalTo(1L)); assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(0).getNestedIdentity().getOffset(), equalTo(1)); - assertThat((Integer) searchHits.getAt(0).getSourceAsMap().get("date"), equalTo(4)); + assertThat(extractValue("comments.date", searchHits.getAt(0).getSourceAsMap()), equalTo(4)); } public void testTopHitsInSecondLayerNested() throws Exception { @@ -802,49 +802,49 @@ public void testTopHitsInSecondLayerNested() throws Exception { assertThat(topReviewers.getHits().getHits().length, equalTo(7)); assertThat(topReviewers.getHits().getAt(0).getId(), equalTo("1")); - assertThat((String) topReviewers.getHits().getAt(0).getSourceAsMap().get("name"), equalTo("user a")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(0).getSourceAsMap()), equalTo("user a")); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getChild().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(1).getId(), equalTo("1")); - assertThat((String) topReviewers.getHits().getAt(1).getSourceAsMap().get("name"), equalTo("user b")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(1).getSourceAsMap()), equalTo("user b")); assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getChild().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(2).getId(), equalTo("1")); - assertThat((String) topReviewers.getHits().getAt(2).getSourceAsMap().get("name"), equalTo("user c")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(2).getSourceAsMap()), equalTo("user c")); assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getChild().getOffset(), equalTo(2)); assertThat(topReviewers.getHits().getAt(3).getId(), equalTo("1")); - assertThat((String) topReviewers.getHits().getAt(3).getSourceAsMap().get("name"), equalTo("user c")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(3).getSourceAsMap()), equalTo("user c")); assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getChild().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(4).getId(), equalTo("1")); - assertThat((String) topReviewers.getHits().getAt(4).getSourceAsMap().get("name"), equalTo("user d")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(4).getSourceAsMap()), equalTo("user d")); assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getChild().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(5).getId(), equalTo("1")); - assertThat((String) topReviewers.getHits().getAt(5).getSourceAsMap().get("name"), equalTo("user e")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(5).getSourceAsMap()), equalTo("user e")); assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getChild().getOffset(), equalTo(2)); assertThat(topReviewers.getHits().getAt(6).getId(), equalTo("2")); - assertThat((String) topReviewers.getHits().getAt(6).getSourceAsMap().get("name"), equalTo("user f")); + assertThat(extractValue("comments.reviewers.name", topReviewers.getHits().getAt(6).getSourceAsMap()), equalTo("user f")); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getChild().getField().string(), equalTo("reviewers")); @@ -900,7 +900,7 @@ public void testNestedFetchFeatures() { assertThat(field.getValue().toString(), equalTo("5")); assertThat(searchHit.getSourceAsMap().size(), equalTo(1)); - assertThat(XContentMapValues.extractValue("comments.message", searchHit.getSourceAsMap()), equalTo("some comment")); + assertThat(extractValue("comments.message", searchHit.getSourceAsMap()), equalTo("some comment")); } public void testTopHitsInNested() throws Exception { @@ -933,7 +933,7 @@ public void testTopHitsInNested() throws Exception { for (int j = 0; j < 3; j++) { assertThat(searchHits.getAt(j).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(j).getNestedIdentity().getOffset(), equalTo(0)); - assertThat((Integer) searchHits.getAt(j).getSourceAsMap().get("id"), equalTo(0)); + assertThat(extractValue("comments.id", searchHits.getAt(j).getSourceAsMap()), equalTo(0)); HighlightField highlightField = searchHits.getAt(j).getHighlightFields().get("comments.message"); assertThat(highlightField.getFragments().length, equalTo(1)); diff --git a/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java b/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java index 3742166a61b3a..55a424754d51f 100644 --- a/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java +++ b/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java @@ -563,7 +563,7 @@ public void testMatchesQueriesNestedInnerHits() throws Exception { } } - public void testNestedSourceFiltering() throws Exception { + public void testNestedSource() throws Exception { assertAcked(prepareCreate("index1").addMapping("message", "comments", "type=nested")); client().prepareIndex("index1", "message", "1").setSource(jsonBuilder().startObject() .field("message", "quick brown fox") @@ -585,6 +585,19 @@ public void testNestedSourceFiltering() throws Exception { assertNoFailures(response); assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getTotalHits(), equalTo(2L)); + assertThat(extractValue("comments.message", response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getSourceAsMap()), + equalTo("fox eat quick")); + assertThat(extractValue("comments.message", response.getHits().getAt(0).getInnerHits().get("comments").getAt(1).getSourceAsMap()), + equalTo("fox ate rabbit x y z")); + + response = client().prepareSearch() + .setQuery(nestedQuery("comments", matchQuery("comments.message", "fox"), ScoreMode.None) + .innerHit(new InnerHitBuilder())) + .get(); + assertNoFailures(response); + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getTotalHits(), equalTo(2L)); assertThat(extractValue("comments.message", response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getSourceAsMap()), equalTo("fox eat quick")); diff --git a/docs/reference/migration/migrate_6_0/search.asciidoc b/docs/reference/migration/migrate_6_0/search.asciidoc index fcde21215257a..020ab625b76e5 100644 --- a/docs/reference/migration/migrate_6_0/search.asciidoc +++ b/docs/reference/migration/migrate_6_0/search.asciidoc @@ -135,4 +135,9 @@ The `unified` highlighter outputs the same highlighting when `index_options` is ==== `fielddata_fields` -The deprecated `fielddata_fields` have now been removed. `docvalue_fields` should be used instead. \ No newline at end of file +The deprecated `fielddata_fields` have now been removed. `docvalue_fields` should be used instead. + +==== Inner hits + +The source inside a hit of inner hits keeps its full path with respect to the entire source. +In prior versions the source field names were relative to the inner hit. diff --git a/docs/reference/search/request/inner-hits.asciidoc b/docs/reference/search/request/inner-hits.asciidoc index a9da737880912..952cdedd423c7 100644 --- a/docs/reference/search/request/inner-hits.asciidoc +++ b/docs/reference/search/request/inner-hits.asciidoc @@ -158,8 +158,10 @@ An example of a response snippet that could be generated from the above search r }, "_score": 1.0, "_source": { - "author": "nik9000", - "number": 2 + "comments" : { + "author": "nik9000", + "number": 2 + } } } ] @@ -404,8 +406,12 @@ Which would look like: }, "_score": 0.6931472, "_source": { - "value": 1, - "voter": "kimchy" + "comments": { + "votes": { + "value": 1, + "voter": "kimchy" + } + } } } ]