-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Shortcut query phase using the results of other shards #51852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 23 commits
28fa23b
534b552
c02f352
010ec08
f5684ec
0acf244
6016fa4
a058127
8534ed2
27cdf19
a313d1d
662972c
76e90a2
7eb98fb
ac0451c
d0ae658
c6747e6
30b3bcb
961c2cd
d04a16d
af20421
291f742
71876e4
b8aa0e2
db4b44f
bd927bd
bf8ebde
30173b6
2e19865
8eae737
ea5727e
f50ec90
ee2591f
4ec6a6c
09bfb09
5e268c6
2307e73
ae1b278
bfd2c72
6489ffe
73aa681
b2504e6
36bec99
74b8bea
7a54222
abda530
06cbc19
74c5d99
e526147
14542f0
8ad41c2
270533c
e4e8b02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,22 +20,33 @@ | |
| package org.elasticsearch.action.search; | ||
|
|
||
| import org.apache.logging.log4j.Logger; | ||
| import org.apache.lucene.search.FieldDoc; | ||
| import org.apache.lucene.search.TopDocs; | ||
| import org.apache.lucene.search.TopFieldDocs; | ||
| import org.elasticsearch.action.ActionListener; | ||
| import org.elasticsearch.cluster.routing.GroupShardsIterator; | ||
| import org.elasticsearch.cluster.routing.ShardRouting; | ||
| import org.elasticsearch.search.SearchPhaseResult; | ||
| import org.elasticsearch.search.builder.SearchSourceBuilder; | ||
| import org.elasticsearch.search.internal.AliasFilter; | ||
| import org.elasticsearch.search.internal.ShardSearchRequest; | ||
| import org.elasticsearch.search.sort.FieldSortBuilder; | ||
| import org.elasticsearch.transport.Transport; | ||
|
|
||
| import java.util.Map; | ||
| import java.util.Set; | ||
| import java.util.concurrent.Executor; | ||
| import java.util.function.BiFunction; | ||
| import java.util.function.Supplier; | ||
|
|
||
| final class SearchQueryThenFetchAsyncAction extends AbstractSearchAsyncAction<SearchPhaseResult> { | ||
| import static org.elasticsearch.action.search.SearchPhaseController.getTopDocsSize; | ||
| import static org.elasticsearch.search.internal.SearchContext.DEFAULT_TRACK_TOTAL_HITS_UP_TO; | ||
|
|
||
| class SearchQueryThenFetchAsyncAction extends AbstractSearchAsyncAction<SearchPhaseResult> { | ||
|
|
||
| private final SearchPhaseController searchPhaseController; | ||
| private final Supplier<TopDocs> topDocsSupplier; | ||
| private final int topDocsSize; | ||
| private final SearchProgressListener progressListener; | ||
|
|
||
| SearchQueryThenFetchAsyncAction(final Logger logger, final SearchTransportService searchTransportService, | ||
|
|
@@ -49,18 +60,20 @@ final class SearchQueryThenFetchAsyncAction extends AbstractSearchAsyncAction<Se | |
| executor, request, listener, shardsIts, timeProvider, clusterStateVersion, task, | ||
| searchPhaseController.newSearchPhaseResults(task.getProgressListener(), request, shardsIts.size()), | ||
| request.getMaxConcurrentShardRequests(), clusters); | ||
| this.topDocsSize = getTopDocsSize(request); | ||
| this.topDocsSupplier = getBufferTopDocsSupplier(request, results); | ||
| this.searchPhaseController = searchPhaseController; | ||
| this.progressListener = task.getProgressListener(); | ||
| final SearchProgressListener progressListener = task.getProgressListener(); | ||
| final SearchSourceBuilder sourceBuilder = request.source(); | ||
| progressListener.notifyListShards(progressListener.searchShards(this.shardsIts), | ||
| sourceBuilder == null || sourceBuilder.size() != 0); | ||
| } | ||
|
|
||
| protected void executePhaseOnShard(final SearchShardIterator shardIt, final ShardRouting shard, | ||
| final SearchActionListener<SearchPhaseResult> listener) { | ||
| ShardSearchRequest request = rewriteShardRequest(buildShardSearchRequest(shardIt)); | ||
| getSearchTransport().sendExecuteQuery(getConnection(shardIt.getClusterAlias(), shard.currentNodeId()), | ||
| buildShardSearchRequest(shardIt), getTask(), listener); | ||
| request, getTask(), listener); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -72,4 +85,38 @@ protected void onShardGroupFailure(int shardIndex, Exception exc) { | |
| protected SearchPhase getNextPhase(final SearchPhaseResults<SearchPhaseResult> results, final SearchPhaseContext context) { | ||
| return new FetchSearchPhase(results, searchPhaseController, context); | ||
| } | ||
|
|
||
| ShardSearchRequest rewriteShardRequest(ShardSearchRequest request) { | ||
|
||
| TopDocs topDocs = topDocsSupplier.get(); | ||
| if (topDocs != null && topDocs instanceof TopFieldDocs) { | ||
| SearchSourceBuilder source = request.source(); | ||
| int trackTotalHits = source.trackTotalHitsUpTo() == null ? DEFAULT_TRACK_TOTAL_HITS_UP_TO : | ||
| source.trackTotalHitsUpTo(); | ||
| if (topDocs.totalHits.value >= trackTotalHits) { | ||
mayya-sharipova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| SearchSourceBuilder newSource = source.shallowCopy(); | ||
| newSource.trackTotalHits(false); | ||
| if (topDocs.scoreDocs.length >= topDocsSize) { | ||
| FieldDoc bottomDoc = (FieldDoc) topDocs.scoreDocs[topDocs.scoreDocs.length-1]; | ||
| request.setRawBottomSortValues(bottomDoc.fields); | ||
| } | ||
| request.source(newSource); | ||
| } | ||
| } | ||
| return request; | ||
| } | ||
|
|
||
| private Supplier<TopDocs> getBufferTopDocsSupplier(SearchRequest request, | ||
| SearchPhaseResults<SearchPhaseResult> searchPhaseResults) { | ||
| if (searchPhaseResults instanceof SearchPhaseController.QueryPhaseResultConsumer == false) { | ||
| return () -> null; | ||
| } | ||
| int size = getTopDocsSize(request); | ||
jimczi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| FieldSortBuilder fieldSort = FieldSortBuilder.getPrimaryFieldSortOrNull(request.source()); | ||
| if (size == 0 | ||
| || fieldSort == null | ||
| || fieldSort.canRewriteToMatchNone() == false) { | ||
| return () -> null; | ||
| } | ||
| return ((SearchPhaseController.QueryPhaseResultConsumer) searchPhaseResults)::getBufferTopDocs; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.