inner hits: Unfiltered nested source should keep its full path

like filtered nested source.

Closes #23090
This commit is contained in:
Martijn van Groningen 2017-08-08 18:05:11 +02:00
parent 3fc27b0e90
commit 076167fbe5
No known key found for this signature in database
GPG Key ID: AB236F4FCF2AF12A
5 changed files with 45 additions and 21 deletions

View File

@ -284,7 +284,7 @@ public class FetchPhase implements SearchPhase {
} }
context.lookup().source().setSource(nestedSourceAsMap); context.lookup().source().setSource(nestedSourceAsMap);
XContentType contentType = tuple.v1(); 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().setSource(nestedSource);
context.lookup().source().setSourceContentType(contentType); context.lookup().source().setSourceContentType(contentType);
} }

View File

@ -28,7 +28,6 @@ import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
@ -67,6 +66,7 @@ import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder; 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.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.nestedQuery; import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
@ -728,7 +728,7 @@ public class TopHitsIT extends ESIntegTestCase {
assertThat(searchHits.getTotalHits(), equalTo(1L)); assertThat(searchHits.getTotalHits(), equalTo(1L));
assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments"));
assertThat(searchHits.getAt(0).getNestedIdentity().getOffset(), equalTo(0)); 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"); bucket = terms.getBucketByKey("b");
assertThat(bucket.getDocCount(), equalTo(2L)); assertThat(bucket.getDocCount(), equalTo(2L));
@ -737,10 +737,10 @@ public class TopHitsIT extends ESIntegTestCase {
assertThat(searchHits.getTotalHits(), equalTo(2L)); assertThat(searchHits.getTotalHits(), equalTo(2L));
assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments"));
assertThat(searchHits.getAt(0).getNestedIdentity().getOffset(), equalTo(1)); 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().getField().string(), equalTo("comments"));
assertThat(searchHits.getAt(1).getNestedIdentity().getOffset(), equalTo(0)); 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"); bucket = terms.getBucketByKey("c");
assertThat(bucket.getDocCount(), equalTo(1L)); assertThat(bucket.getDocCount(), equalTo(1L));
@ -749,7 +749,7 @@ public class TopHitsIT extends ESIntegTestCase {
assertThat(searchHits.getTotalHits(), equalTo(1L)); assertThat(searchHits.getTotalHits(), equalTo(1L));
assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments"));
assertThat(searchHits.getAt(0).getNestedIdentity().getOffset(), equalTo(1)); 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 { public void testTopHitsInSecondLayerNested() throws Exception {
@ -802,49 +802,49 @@ public class TopHitsIT extends ESIntegTestCase {
assertThat(topReviewers.getHits().getHits().length, equalTo(7)); assertThat(topReviewers.getHits().getHits().length, equalTo(7));
assertThat(topReviewers.getHits().getAt(0).getId(), equalTo("1")); 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getOffset(), equalTo(0)); 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().getField().string(), equalTo("reviewers"));
assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getChild().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getChild().getOffset(), equalTo(0));
assertThat(topReviewers.getHits().getAt(1).getId(), equalTo("1")); 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getOffset(), equalTo(0)); 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().getField().string(), equalTo("reviewers"));
assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getChild().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(1).getNestedIdentity().getChild().getOffset(), equalTo(1));
assertThat(topReviewers.getHits().getAt(2).getId(), 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getOffset(), equalTo(0)); 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().getField().string(), equalTo("reviewers"));
assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getChild().getOffset(), equalTo(2)); assertThat(topReviewers.getHits().getAt(2).getNestedIdentity().getChild().getOffset(), equalTo(2));
assertThat(topReviewers.getHits().getAt(3).getId(), equalTo("1")); 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getOffset(), equalTo(1)); 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().getField().string(), equalTo("reviewers"));
assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getChild().getOffset(), equalTo(0)); assertThat(topReviewers.getHits().getAt(3).getNestedIdentity().getChild().getOffset(), equalTo(0));
assertThat(topReviewers.getHits().getAt(4).getId(), equalTo("1")); 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getOffset(), equalTo(1)); 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().getField().string(), equalTo("reviewers"));
assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getChild().getOffset(), equalTo(1)); assertThat(topReviewers.getHits().getAt(4).getNestedIdentity().getChild().getOffset(), equalTo(1));
assertThat(topReviewers.getHits().getAt(5).getId(), 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getOffset(), equalTo(1)); 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().getField().string(), equalTo("reviewers"));
assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getChild().getOffset(), equalTo(2)); assertThat(topReviewers.getHits().getAt(5).getNestedIdentity().getChild().getOffset(), equalTo(2));
assertThat(topReviewers.getHits().getAt(6).getId(), 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().getField().string(), equalTo("comments"));
assertThat(topReviewers.getHits().getAt(0).getNestedIdentity().getOffset(), equalTo(0)); 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().getField().string(), equalTo("reviewers"));
@ -900,7 +900,7 @@ public class TopHitsIT extends ESIntegTestCase {
assertThat(field.getValue().toString(), equalTo("5")); assertThat(field.getValue().toString(), equalTo("5"));
assertThat(searchHit.getSourceAsMap().size(), equalTo(1)); 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 { public void testTopHitsInNested() throws Exception {
@ -933,7 +933,7 @@ public class TopHitsIT extends ESIntegTestCase {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
assertThat(searchHits.getAt(j).getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHits.getAt(j).getNestedIdentity().getField().string(), equalTo("comments"));
assertThat(searchHits.getAt(j).getNestedIdentity().getOffset(), equalTo(0)); 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"); HighlightField highlightField = searchHits.getAt(j).getHighlightFields().get("comments.message");
assertThat(highlightField.getFragments().length, equalTo(1)); assertThat(highlightField.getFragments().length, equalTo(1));

View File

@ -563,7 +563,7 @@ public class InnerHitsIT extends ESIntegTestCase {
} }
} }
public void testNestedSourceFiltering() throws Exception { public void testNestedSource() throws Exception {
assertAcked(prepareCreate("index1").addMapping("message", "comments", "type=nested")); assertAcked(prepareCreate("index1").addMapping("message", "comments", "type=nested"));
client().prepareIndex("index1", "message", "1").setSource(jsonBuilder().startObject() client().prepareIndex("index1", "message", "1").setSource(jsonBuilder().startObject()
.field("message", "quick brown fox") .field("message", "quick brown fox")
@ -585,6 +585,19 @@ public class InnerHitsIT extends ESIntegTestCase {
assertNoFailures(response); assertNoFailures(response);
assertHitCount(response, 1); 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(response.getHits().getAt(0).getInnerHits().get("comments").getTotalHits(), equalTo(2L));
assertThat(extractValue("comments.message", response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getSourceAsMap()), assertThat(extractValue("comments.message", response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getSourceAsMap()),
equalTo("fox eat quick")); equalTo("fox eat quick"));

View File

@ -135,4 +135,9 @@ The `unified` highlighter outputs the same highlighting when `index_options` is
==== `fielddata_fields` ==== `fielddata_fields`
The deprecated `fielddata_fields` have now been removed. `docvalue_fields` should be used instead. 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.

View File

@ -158,8 +158,10 @@ An example of a response snippet that could be generated from the above search r
}, },
"_score": 1.0, "_score": 1.0,
"_source": { "_source": {
"author": "nik9000", "comments" : {
"number": 2 "author": "nik9000",
"number": 2
}
} }
} }
] ]
@ -404,8 +406,12 @@ Which would look like:
}, },
"_score": 0.6931472, "_score": 0.6931472,
"_source": { "_source": {
"value": 1, "comments": {
"voter": "kimchy" "votes": {
"value": 1,
"voter": "kimchy"
}
}
} }
} }
] ]