Skip to content

Commit dd587d1

Browse files
Merge branch 'main' into sa-fix-internal-cluster-tests
2 parents d2587b1 + 66d18d0 commit dd587d1

File tree

7 files changed

+38
-34
lines changed

7 files changed

+38
-34
lines changed

docs/changelog/122575.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 122575
2+
summary: Return an empty suggestion when suggest phase times out
3+
area: Suggesters
4+
type: bug
5+
issues:
6+
- 122548

muted-tests.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,6 @@ tests:
323323
issue: https://github.com/elastic/elasticsearch/issues/122378
324324
- class: org.elasticsearch.telemetry.apm.ApmAgentSettingsIT
325325
issue: https://github.com/elastic/elasticsearch/issues/122546
326-
- class: org.elasticsearch.search.SearchTimeoutIT
327-
method: testSuggestTimeoutWithPartialResults
328-
issue: https://github.com/elastic/elasticsearch/issues/122548
329326
- class: org.elasticsearch.xpack.inference.mapper.SemanticInferenceMetadataFieldsRecoveryTests
330327
method: testSnapshotRecovery {p0=false p1=false}
331328
issue: https://github.com/elastic/elasticsearch/issues/122549

server/src/internalClusterTest/java/org/elasticsearch/search/SearchTimeoutIT.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,7 @@ protected TermSuggestion innerExecute(
484484
CharsRefBuilder spare
485485
) {
486486
contextIndexSearcher.throwTimeExceededException();
487-
assert false;
488-
return new TermSuggestion(name, suggestion.getSize(), SortBy.SCORE);
487+
throw new AssertionError("should have thrown TimeExceededException");
489488
}
490489

491490
@Override

server/src/main/java/org/elasticsearch/search/query/QueryPhase.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,7 @@ static void executeRank(SearchContext searchContext) throws QueryPhaseExecutionE
126126

127127
static void executeQuery(SearchContext searchContext) throws QueryPhaseExecutionException {
128128
if (searchContext.hasOnlySuggest()) {
129-
try {
130-
SuggestPhase.execute(searchContext);
131-
} catch (ContextIndexSearcher.TimeExceededException timeExceededException) {
132-
SearchTimeoutException.handleTimeout(
133-
searchContext.request().allowPartialSearchResults(),
134-
searchContext.shardTarget(),
135-
searchContext.queryResult()
136-
);
137-
}
129+
SuggestPhase.execute(searchContext);
138130
searchContext.queryResult().topDocs(new TopDocsAndMaxScore(Lucene.EMPTY_TOP_DOCS, Float.NaN), new DocValueFormat[0]);
139131
return;
140132
}
@@ -150,18 +142,10 @@ static void executeQuery(SearchContext searchContext) throws QueryPhaseExecution
150142

151143
addCollectorsAndSearch(searchContext);
152144

153-
try {
154-
RescorePhase.execute(searchContext);
155-
SuggestPhase.execute(searchContext);
156-
if (searchContext.getProfilers() != null) {
157-
searchContext.queryResult().profileResults(searchContext.getProfilers().buildQueryPhaseResults());
158-
}
159-
} catch (ContextIndexSearcher.TimeExceededException timeExceededException) {
160-
SearchTimeoutException.handleTimeout(
161-
searchContext.request().allowPartialSearchResults(),
162-
searchContext.shardTarget(),
163-
searchContext.queryResult()
164-
);
145+
RescorePhase.execute(searchContext);
146+
SuggestPhase.execute(searchContext);
147+
if (searchContext.getProfilers() != null) {
148+
searchContext.queryResult().profileResults(searchContext.getProfilers().buildQueryPhaseResults());
165149
}
166150
}
167151

server/src/main/java/org/elasticsearch/search/rescore/RescorePhase.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import org.elasticsearch.common.lucene.search.TopDocsAndMaxScore;
1919
import org.elasticsearch.common.util.Maps;
2020
import org.elasticsearch.lucene.grouping.TopFieldGroups;
21+
import org.elasticsearch.search.internal.ContextIndexSearcher;
2122
import org.elasticsearch.search.internal.SearchContext;
23+
import org.elasticsearch.search.query.SearchTimeoutException;
2224
import org.elasticsearch.search.sort.ShardDocSortField;
2325
import org.elasticsearch.search.sort.SortAndFormats;
2426

@@ -84,6 +86,13 @@ public static void execute(SearchContext context) {
8486
.topDocs(new TopDocsAndMaxScore(topDocs, topDocs.scoreDocs[0].score), context.queryResult().sortValueFormats());
8587
} catch (IOException e) {
8688
throw new ElasticsearchException("Rescore Phase Failed", e);
89+
} catch (ContextIndexSearcher.TimeExceededException timeExceededException) {
90+
SearchTimeoutException.handleTimeout(
91+
context.request().allowPartialSearchResults(),
92+
context.shardTarget(),
93+
context.queryResult()
94+
);
95+
// if the rescore phase times out and partial results are allowed, the returned top docs from this shard won't be rescored
8796
}
8897
}
8998

server/src/main/java/org/elasticsearch/search/suggest/SuggestPhase.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010

1111
import org.apache.lucene.util.CharsRefBuilder;
1212
import org.elasticsearch.ElasticsearchException;
13+
import org.elasticsearch.search.internal.ContextIndexSearcher;
1314
import org.elasticsearch.search.internal.SearchContext;
15+
import org.elasticsearch.search.query.SearchTimeoutException;
1416
import org.elasticsearch.search.suggest.Suggest.Suggestion;
1517
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry;
1618
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option;
@@ -40,12 +42,17 @@ public static void execute(SearchContext context) {
4042
for (Map.Entry<String, SuggestionSearchContext.SuggestionContext> entry : suggest.suggestions().entrySet()) {
4143
SuggestionSearchContext.SuggestionContext suggestion = entry.getValue();
4244
Suggester<SuggestionContext> suggester = suggestion.getSuggester();
43-
Suggestion<? extends Entry<? extends Option>> result = suggester.execute(
44-
entry.getKey(),
45-
suggestion,
46-
context.searcher(),
47-
spare
48-
);
45+
Suggestion<? extends Entry<? extends Option>> result;
46+
try {
47+
result = suggester.execute(entry.getKey(), suggestion, context.searcher(), spare);
48+
} catch (ContextIndexSearcher.TimeExceededException timeExceededException) {
49+
SearchTimeoutException.handleTimeout(
50+
context.request().allowPartialSearchResults(),
51+
context.shardTarget(),
52+
context.queryResult()
53+
);
54+
result = suggester.emptySuggestion(entry.getKey(), suggestion, spare);
55+
}
4956
if (result != null) {
5057
assert entry.getKey().equals(result.name);
5158
suggestions.add(result);

server/src/test/java/org/elasticsearch/search/query/QueryPhaseTimeoutTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ public void testSuggestOnlyWithTimeout() throws Exception {
297297
assertTrue(context.hasOnlySuggest());
298298
QueryPhase.execute(context);
299299
assertTrue(context.queryResult().searchTimedOut());
300-
assertNull(context.queryResult().suggest());
300+
assertEquals(1, context.queryResult().suggest().size());
301+
assertEquals(0, context.queryResult().suggest().getSuggestion("suggestion").getEntries().size());
301302
assertNotNull(context.queryResult().topDocs());
302303
assertEquals(0, context.queryResult().topDocs().topDocs.totalHits.value());
303304
}
@@ -311,7 +312,8 @@ public void testSuggestAndQueryWithSuggestTimeout() throws Exception {
311312
QueryPhase.execute(context);
312313
assertThat(context.queryResult().topDocs().topDocs.totalHits.value(), Matchers.greaterThan(0L));
313314
assertTrue(context.queryResult().searchTimedOut());
314-
assertNull(context.queryResult().suggest());
315+
assertEquals(1, context.queryResult().suggest().size());
316+
assertEquals(0, context.queryResult().suggest().getSuggestion("suggestion").getEntries().size());
315317
}
316318
}
317319

0 commit comments

Comments
 (0)