Skip to content

Commit 6ca8524

Browse files
committed
Switch back to copy pattern, with search execution context override
1 parent d3803a7 commit 6ca8524

File tree

5 files changed

+99
-21
lines changed

5 files changed

+99
-21
lines changed

modules/parent-join/src/main/java/org/elasticsearch/join/query/ParentChildInnerHitContextBuilder.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,35 @@ static final class JoinFieldInnerHitSubContext extends InnerHitsContext.InnerHit
8888
private final String typeName;
8989
private final boolean fetchChildInnerHits;
9090
private final Joiner joiner;
91+
private final SearchExecutionContext searchExecutionContext;
9192

9293
JoinFieldInnerHitSubContext(String name, SearchContext context, String typeName, boolean fetchChildInnerHits, Joiner joiner) {
9394
super(name, context);
9495
this.typeName = typeName;
9596
this.fetchChildInnerHits = fetchChildInnerHits;
9697
this.joiner = joiner;
98+
this.searchExecutionContext = null;
99+
}
100+
101+
JoinFieldInnerHitSubContext(
102+
JoinFieldInnerHitSubContext joinFieldInnerHitSubContext,
103+
SearchExecutionContext searchExecutionContext
104+
) {
105+
super(joinFieldInnerHitSubContext);
106+
this.typeName = joinFieldInnerHitSubContext.typeName;
107+
this.fetchChildInnerHits = joinFieldInnerHitSubContext.fetchChildInnerHits;
108+
this.joiner = joinFieldInnerHitSubContext.joiner;
109+
this.searchExecutionContext = searchExecutionContext;
110+
}
111+
112+
@Override
113+
public JoinFieldInnerHitSubContext copyWithSearchExecutionContext(SearchExecutionContext searchExecutionContext) {
114+
return new JoinFieldInnerHitSubContext(this, searchExecutionContext);
115+
}
116+
117+
@Override
118+
public SearchExecutionContext getSearchExecutionContext() {
119+
return searchExecutionContext != null ? searchExecutionContext : super.getSearchExecutionContext();
97120
}
98121

99122
@Override

server/src/internalClusterTest/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.elasticsearch.action.index.IndexRequestBuilder;
1616
import org.elasticsearch.action.search.SearchPhaseExecutionException;
1717
import org.elasticsearch.action.search.SearchType;
18-
import org.elasticsearch.cluster.metadata.IndexMetadata;
1918
import org.elasticsearch.common.document.DocumentField;
2019
import org.elasticsearch.common.settings.Settings;
2120
import org.elasticsearch.index.IndexSettings;
@@ -49,6 +48,7 @@
4948
import org.elasticsearch.search.lookup.FieldLookup;
5049
import org.elasticsearch.search.lookup.LeafSearchLookup;
5150
import org.elasticsearch.search.rescore.QueryRescorerBuilder;
51+
import org.elasticsearch.search.sort.NestedSortBuilder;
5252
import org.elasticsearch.search.sort.ScriptSortBuilder.ScriptSortType;
5353
import org.elasticsearch.search.sort.SortBuilders;
5454
import org.elasticsearch.search.sort.SortOrder;
@@ -988,18 +988,63 @@ public void testTopHitsInNested() throws Exception {
988988
}
989989

990990
public void testTopHitsOnInnerHits() {
991-
QueryBuilder qb = nestedQuery("comments", matchQuery("comments.message", "text"), ScoreMode.Avg).innerHit(new InnerHitBuilder());
992-
AggregationBuilder ab = topHits("top-comments").size(3);
991+
QueryBuilder nestedQuery = nestedQuery("comments", matchQuery("comments.message", "text"), ScoreMode.Avg).innerHit(
992+
new InnerHitBuilder().setSize(2)
993+
);
994+
AggregationBuilder topHitsAgg = topHits("top-comments").size(3)
995+
.sort(SortBuilders.fieldSort("comments.date").order(SortOrder.ASC).setNestedSort(new NestedSortBuilder("comments")));
993996

994-
assertNoFailuresAndResponse(prepareSearch("articles").setQuery(qb).addAggregation(ab), response -> {
997+
assertNoFailuresAndResponse(prepareSearch("articles").setQuery(nestedQuery).addAggregation(topHitsAgg), response -> {
995998
TopHits topHits = response.getAggregations().get("top-comments");
996999
SearchHits hits = topHits.getHits();
9971000
assertThat(hits.getHits().length, equalTo(3));
9981001

999-
SearchHit searchHit = hits.getAt(0);
1000-
SearchHits innerHits = searchHit.getInnerHits().get("comments");
1001-
assertThat(innerHits.getHits().length, equalTo(3));
1002-
assertThat(innerHits.getAt(0).getNestedIdentity().getField().toString(), equalTo("comments"));
1002+
for (SearchHit hit : hits) {
1003+
SearchHits innerHits = hit.getInnerHits().get("comments");
1004+
assertThat(innerHits.getHits().length, lessThanOrEqualTo(2));
1005+
for (SearchHit innerHit : innerHits) {
1006+
assertThat(innerHit.getNestedIdentity().getField().string(), equalTo("comments"));
1007+
Map<String, Object> source = innerHit.getSourceAsMap();
1008+
assertTrue(source.containsKey("message"));
1009+
assertFalse(source.containsKey("reviewers"));
1010+
}
1011+
}
1012+
});
1013+
}
1014+
1015+
public void testTopHitsOnMultipleNestedInnerHits() {
1016+
QueryBuilder doubleNestedQuery = nestedQuery(
1017+
"comments",
1018+
nestedQuery("comments.reviewers", matchQuery("comments.reviewers.name", "user c"), ScoreMode.Avg).innerHit(
1019+
new InnerHitBuilder()
1020+
),
1021+
ScoreMode.Avg
1022+
).innerHit(new InnerHitBuilder("review"));
1023+
AggregationBuilder topHitsAgg = topHits("top-reviewers").size(2)
1024+
.sort(SortBuilders.fieldSort("comments.date").order(SortOrder.ASC).setNestedSort(new NestedSortBuilder("comments")));
1025+
1026+
assertNoFailuresAndResponse(prepareSearch("articles").setQuery(doubleNestedQuery).addAggregation(topHitsAgg), response -> {
1027+
TopHits topHits = response.getAggregations().get("top-reviewers");
1028+
SearchHits hits = topHits.getHits();
1029+
assertThat(hits.getHits().length, equalTo(1));
1030+
1031+
SearchHit hit = hits.getAt(0);
1032+
SearchHits innerHits = hit.getInnerHits().get("review");
1033+
assertThat(innerHits.getHits().length, equalTo(2));
1034+
1035+
assertThat(innerHits.getAt(0).getId(), equalTo("1"));
1036+
assertThat(innerHits.getAt(0).getNestedIdentity().getField().string(), equalTo("comments"));
1037+
assertThat(innerHits.getAt(0).getNestedIdentity().getOffset(), equalTo(0));
1038+
Map<String, Object> source0 = innerHits.getAt(0).getSourceAsMap();
1039+
assertTrue(source0.containsKey("message"));
1040+
assertTrue(source0.containsKey("reviewers"));
1041+
1042+
assertThat(innerHits.getAt(1).getId(), equalTo("1"));
1043+
assertThat(innerHits.getAt(1).getNestedIdentity().getField().string(), equalTo("comments"));
1044+
assertThat(innerHits.getAt(1).getNestedIdentity().getOffset(), equalTo(1));
1045+
Map<String, Object> source1 = innerHits.getAt(1).getSourceAsMap();
1046+
assertTrue(source1.containsKey("message"));
1047+
assertTrue(source1.containsKey("reviewers"));
10031048
});
10041049
}
10051050

server/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ static final class NestedInnerHitSubContext extends InnerHitsContext.InnerHitSub
396396

397397
private final NestedObjectMapper parentObjectMapper;
398398
private final NestedObjectMapper childObjectMapper;
399+
private final SearchExecutionContext searchExecutionContext;
399400

400401
NestedInnerHitSubContext(
401402
String name,
@@ -406,6 +407,24 @@ static final class NestedInnerHitSubContext extends InnerHitsContext.InnerHitSub
406407
super(name, context);
407408
this.parentObjectMapper = parentObjectMapper;
408409
this.childObjectMapper = childObjectMapper;
410+
this.searchExecutionContext = null;
411+
}
412+
413+
NestedInnerHitSubContext(NestedInnerHitSubContext nestedInnerHitSubContext, SearchExecutionContext searchExecutionContext) {
414+
super(nestedInnerHitSubContext);
415+
this.parentObjectMapper = nestedInnerHitSubContext.parentObjectMapper;
416+
this.childObjectMapper = nestedInnerHitSubContext.childObjectMapper;
417+
this.searchExecutionContext = searchExecutionContext;
418+
}
419+
420+
@Override
421+
public NestedInnerHitSubContext copyWithSearchExecutionContext(SearchExecutionContext searchExecutionContext) {
422+
return new NestedInnerHitSubContext(this, searchExecutionContext);
423+
}
424+
425+
@Override
426+
public SearchExecutionContext getSearchExecutionContext() {
427+
return searchExecutionContext != null ? searchExecutionContext : super.getSearchExecutionContext();
409428
}
410429

411430
@Override

server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -252,19 +252,7 @@ private static Map<String, InnerHitSubContext> getForkedInnerHits(
252252
) {
253253
Map<String, InnerHitSubContext> forkedInnerHits = new HashMap<>();
254254
for (Map.Entry<String, InnerHitSubContext> entry : originalInnerHits.entrySet()) {
255-
var originalContext = entry.getValue();
256-
var forkedContext = new InnerHitSubContext(originalContext) {
257-
@Override
258-
public SearchExecutionContext getSearchExecutionContext() {
259-
return searchExecutionContext;
260-
}
261-
262-
// Delegate top docs to the original InnerHitSubContext, it does not need to be changed
263-
@Override
264-
public TopDocsAndMaxScore topDocs(SearchHit hit) throws IOException {
265-
return originalContext.topDocs(hit);
266-
}
267-
};
255+
var forkedContext = entry.getValue().copyWithSearchExecutionContext(searchExecutionContext);
268256
forkedInnerHits.put(entry.getKey(), forkedContext);
269257
}
270258

server/src/main/java/org/elasticsearch/search/fetch/subphase/InnerHitsContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.lucene.search.Weight;
2323
import org.apache.lucene.util.Bits;
2424
import org.elasticsearch.common.lucene.search.TopDocsAndMaxScore;
25+
import org.elasticsearch.index.query.SearchExecutionContext;
2526
import org.elasticsearch.search.SearchHit;
2627
import org.elasticsearch.search.internal.SearchContext;
2728
import org.elasticsearch.search.internal.SubSearchContext;
@@ -90,6 +91,8 @@ public InnerHitSubContext(InnerHitSubContext innerHitSubContext) {
9091
this.context = innerHitSubContext.context;
9192
}
9293

94+
public abstract InnerHitSubContext copyWithSearchExecutionContext(SearchExecutionContext searchExecutionContext);
95+
9396
public abstract TopDocsAndMaxScore topDocs(SearchHit hit) throws IOException;
9497

9598
public String getName() {

0 commit comments

Comments
 (0)