Skip to content

Commit dcfe174

Browse files
committed
Use new search lookup for each inner hits context
1 parent 7fd8be8 commit dcfe174

File tree

7 files changed

+52
-23
lines changed

7 files changed

+52
-23
lines changed

server/src/internalClusterTest/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
package org.elasticsearch.search.fetch.subphase;
1010

11-
import com.carrotsearch.randomizedtesting.annotations.Seed;
1211
import org.apache.lucene.search.join.ScoreMode;
1312
import org.apache.lucene.util.ArrayUtil;
1413
import org.elasticsearch.action.index.IndexRequestBuilder;
@@ -61,14 +60,18 @@
6160
import static org.hamcrest.Matchers.notNullValue;
6261
import static org.hamcrest.Matchers.nullValue;
6362

64-
@Seed("9E43F62788D47F1E:E99EDE15224E9745")
6563
public class InnerHitsIT extends ESIntegTestCase {
6664

6765
@Override
6866
protected Collection<Class<? extends Plugin>> nodePlugins() {
6967
return Arrays.asList(InternalSettingsPlugin.class, CustomScriptPlugin.class);
7068
}
7169

70+
@Override
71+
protected int numberOfShards() {
72+
return 1;
73+
}
74+
7275
public static class CustomScriptPlugin extends MockScriptPlugin {
7376
@Override
7477
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
@@ -197,12 +200,12 @@ public void testRandomNested() throws Exception {
197200
.field("foo", i)
198201
.startArray("field1");
199202
for (int j = 0; j < numInnerObjects; j++) {
200-
source.startObject().field("x", "y").endObject();
203+
source.startObject().field("x", "y" + i + ":" + j).endObject();
201204
}
202205
numInnerObjects = field2InnerObjects[i] = scaledRandomIntBetween(1, numDocs);
203206
source.endArray().startArray("field2");
204207
for (int j = 0; j < numInnerObjects; j++) {
205-
source.startObject().field("x", "y").endObject();
208+
source.startObject().field("p", "q" + i + ":" + j).endObject();
206209
}
207210
source.endArray().endObject();
208211
requestBuilders.add(client().prepareIndex("idx").setId(Integer.toString(i)).setSource(source));

server/src/main/java/org/elasticsearch/search/fetch/FetchContext.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.elasticsearch.search.fetch.subphase.highlight.SearchHighlightContext;
2323
import org.elasticsearch.search.internal.ContextIndexSearcher;
2424
import org.elasticsearch.search.internal.SearchContext;
25-
import org.elasticsearch.search.lookup.SearchLookup;
2625
import org.elasticsearch.search.lookup.SourceLookup;
2726
import org.elasticsearch.search.rescore.RescoreContext;
2827

@@ -35,14 +34,12 @@
3534
public class FetchContext {
3635

3736
private final SearchContext searchContext;
38-
private final SearchLookup searchLookup;
3937

4038
/**
4139
* Create a FetchContext based on a SearchContext
4240
*/
4341
public FetchContext(SearchContext searchContext) {
4442
this.searchContext = searchContext;
45-
this.searchLookup = searchContext.getSearchExecutionContext().lookup();
4643
}
4744

4845
/**
@@ -59,13 +56,6 @@ public ContextIndexSearcher searcher() {
5956
return searchContext.searcher();
6057
}
6158

62-
/**
63-
* The {@code SearchLookup} for the this context
64-
*/
65-
public SearchLookup searchLookup() {
66-
return searchLookup;
67-
}
68-
6959
/**
7060
* The original query
7161
*/

server/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.elasticsearch.search.fetch.subphase.InnerHitsPhase;
3838
import org.elasticsearch.search.internal.SearchContext;
3939
import org.elasticsearch.search.lookup.LeafSearchLookup;
40+
import org.elasticsearch.search.lookup.SearchLookup;
4041
import org.elasticsearch.search.lookup.SourceLookup;
4142
import org.elasticsearch.search.lookup.ValuesLookup;
4243
import org.elasticsearch.tasks.TaskCancelledException;
@@ -102,6 +103,7 @@ public void execute(SearchContext context) {
102103

103104
List<FetchSubPhaseProcessor> processors = getProcessors(context.shardTarget(), fetchContext);
104105
NestedDocuments nestedDocuments = context.getSearchExecutionContext().getNestedDocuments();
106+
SearchLookup searchLookup = context.getSearchLookup();
105107

106108
int currentReaderIndex = -1;
107109
LeafReaderContext currentReaderContext = null;
@@ -134,11 +136,11 @@ public void execute(SearchContext context) {
134136
processor.setNextReader(currentReaderContext);
135137
}
136138
leafNestedDocuments = nestedDocuments.getLeafNestedDocuments(currentReaderContext);
137-
currentValuesLookup = fetchContext.searchLookup().getLeafSearchLookup(currentReaderContext);
139+
currentValuesLookup = searchLookup.getLeafSearchLookup(currentReaderContext);
138140
}
139141
assert currentReaderContext != null;
140142
assert currentValuesLookup != null;
141-
currentValuesLookup.setDocument(docId);
143+
currentValuesLookup.setDocument(docId - currentReaderContext.docBase);
142144
HitContext hit = prepareHitContext(
143145
context,
144146
leafNestedDocuments,
@@ -377,9 +379,6 @@ private HitContext prepareNestedHitContext(SearchContext context,
377379

378380
SearchHit.NestedIdentity nestedIdentity = nestedInfo.nestedIdentity();
379381

380-
SearchHit hit = new SearchHit(topDocId, rootId, nestedIdentity, docFields, metaFields);
381-
HitContext hitContext = new HitContext(hit, valuesLookup, subReaderContext, nestedInfo.doc());
382-
383382
if (rootSourceAsMap != null && rootSourceAsMap.isEmpty() == false) {
384383
// Isolate the nested json array object that matches with nested hit and wrap it back into the same json
385384
// structure with the nested json array object being the actual content. The latter is important, so that
@@ -413,10 +412,10 @@ private HitContext prepareNestedHitContext(SearchContext context,
413412
}
414413
}
415414

416-
hitContext.valuesLookup().source().setSource(nestedSourceAsMap);
417-
hitContext.valuesLookup().source().setSourceContentType(rootSourceContentType);
415+
valuesLookup = ValuesLookup.wrapWithSource(valuesLookup, nestedSourceAsMap, rootSourceContentType);
418416
}
419-
return hitContext;
417+
SearchHit hit = new SearchHit(topDocId, rootId, nestedIdentity, docFields, metaFields);
418+
return new HitContext(hit, valuesLookup, subReaderContext, nestedInfo.doc());
420419
}
421420

422421
private void loadStoredFields(Function<String, MappedFieldType> fieldTypeLookup,

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import org.apache.lucene.search.Weight;
2222
import org.apache.lucene.util.Bits;
2323
import org.elasticsearch.common.lucene.search.TopDocsAndMaxScore;
24+
import org.elasticsearch.index.query.SearchExecutionContext;
2425
import org.elasticsearch.search.SearchHit;
2526
import org.elasticsearch.search.internal.SearchContext;
2627
import org.elasticsearch.search.internal.SubSearchContext;
28+
import org.elasticsearch.search.lookup.SearchLookup;
2729
import org.elasticsearch.search.lookup.SourceLookup;
2830

2931
import java.io.IOException;
@@ -69,6 +71,7 @@ public abstract static class InnerHitSubContext extends SubSearchContext {
6971
protected final SearchContext context;
7072
private InnerHitsContext childInnerHits;
7173
private Weight innerHitQueryWeight;
74+
private SearchLookup searchLookup;
7275

7376
private String rootId;
7477
private final SourceLookup rootLookup = new SourceLookup();
@@ -134,6 +137,15 @@ public void setRootLookup(SourceLookup rootLookup) {
134137
this.rootLookup.setSource(rootLookup.source());
135138
this.rootLookup.setSourceContentType(rootLookup.sourceContentType());
136139
}
140+
141+
@Override
142+
public SearchLookup getSearchLookup() {
143+
if (this.searchLookup == null) {
144+
SearchExecutionContext sec = getSearchExecutionContext();
145+
this.searchLookup = new SearchLookup(sec::getFieldType, (f, l) -> sec.getForField(f));
146+
}
147+
return this.searchLookup;
148+
}
137149
}
138150

139151
public static void intersect(Weight weight, Weight innerHitQueryWeight, Collector collector, LeafReaderContext ctx) throws IOException {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public InnerHitsPhase(FetchPhase fetchPhase) {
3535

3636
@Override
3737
public FetchSubPhaseProcessor getProcessor(FetchContext searchContext) {
38-
if (searchContext.innerHits() == null) {
38+
if (searchContext.innerHits() == null || searchContext.innerHits().getInnerHits().isEmpty()) {
3939
return null;
4040
}
4141
Map<String, InnerHitsContext.InnerHitSubContext> innerHits = searchContext.innerHits().getInnerHits();

server/src/main/java/org/elasticsearch/search/internal/SearchContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.elasticsearch.search.fetch.subphase.InnerHitsContext;
3737
import org.elasticsearch.search.fetch.subphase.ScriptFieldsContext;
3838
import org.elasticsearch.search.fetch.subphase.highlight.SearchHighlightContext;
39+
import org.elasticsearch.search.lookup.SearchLookup;
3940
import org.elasticsearch.search.profile.Profilers;
4041
import org.elasticsearch.search.query.QuerySearchResult;
4142
import org.elasticsearch.search.rescore.RescoreContext;
@@ -335,6 +336,10 @@ public final boolean hasOnlySuggest() {
335336

336337
public abstract SearchExecutionContext getSearchExecutionContext();
337338

339+
public SearchLookup getSearchLookup() {
340+
return getSearchExecutionContext().lookup();
341+
}
342+
338343
@Override
339344
public String toString() {
340345
StringBuilder result = new StringBuilder().append(shardTarget());

server/src/main/java/org/elasticsearch/search/lookup/ValuesLookup.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,35 @@
99
package org.elasticsearch.search.lookup;
1010

1111
import org.elasticsearch.common.bytes.BytesReference;
12+
import org.elasticsearch.common.xcontent.XContentType;
1213

1314
import java.util.Map;
15+
import java.util.Objects;
1416

1517
public interface ValuesLookup {
1618

1719
SourceLookup source();
1820

1921
LeafDocLookup doc();
2022

23+
static ValuesLookup wrapWithSource(ValuesLookup in, Map<String, Object> source, XContentType xContentType) {
24+
System.out.println("Building independent source: " + source);
25+
SourceLookup sourceLookup = new SourceLookup();
26+
sourceLookup.setSource(source);
27+
sourceLookup.setSourceContentType(Objects.requireNonNull(xContentType));
28+
return new ValuesLookup() {
29+
@Override
30+
public SourceLookup source() {
31+
return sourceLookup;
32+
}
33+
34+
@Override
35+
public LeafDocLookup doc() {
36+
return in.doc();
37+
}
38+
};
39+
}
40+
2141
static ValuesLookup sourceOnly(BytesReference source) {
2242
SourceLookup sourceLookup = new SourceLookup();
2343
sourceLookup.setSource(source);

0 commit comments

Comments
 (0)