Skip to content

Commit a7bdf1f

Browse files
-noise
1 parent 7f9b9c5 commit a7bdf1f

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

server/src/main/java/org/elasticsearch/action/search/SearchQueryThenFetchAsyncAction.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,13 @@ private static ShardSearchRequest tryRewriteWithUpdatedSortValue(
401401
// disable tracking total hits if we already reached the required estimation.
402402
if (trackTotalHitsUpTo != SearchContext.TRACK_TOTAL_HITS_ACCURATE && bottomSortCollector.getTotalHits() > trackTotalHitsUpTo) {
403403
request.source(request.source().shallowCopy().trackTotalHits(false));
404+
request.setRunCanMatchInQueryPhase(true);
404405
}
405406

406407
// set the current best bottom field doc
407408
if (bottomSortCollector.getBottomSortValues() != null) {
408409
request.setBottomSortValues(bottomSortCollector.getBottomSortValues());
410+
request.setRunCanMatchInQueryPhase(true);
409411
}
410412
return request;
411413
}
@@ -467,30 +469,32 @@ protected void doRun(Map<SearchShardIterator, Integer> shardIndexMap) {
467469
transportService.getThreadPool().executor(ThreadPool.Names.SEARCH_COORDINATION).execute(new AbstractRunnable() {
468470
@Override
469471
protected void doRun() {
470-
if (hasPrimaryFieldSort(request.source())) {
472+
var shards = localNodeRequest.shards;
473+
if (shards.size() > 1 && hasPrimaryFieldSort(request.source())) {
471474
@SuppressWarnings("rawtypes")
472-
final MinAndMax[] minAndMax = new MinAndMax[localNodeRequest.shards.size()];
475+
final MinAndMax[] minAndMax = new MinAndMax[shards.size()];
473476
for (int i = 0; i < minAndMax.length; i++) {
474-
minAndMax[i] = searchService.canMatch(
475-
buildShardSearchRequestForLocal(localNodeRequest, localNodeRequest.shards.get(i))
476-
).estimatedMinAndMax();
477+
// TODO: refactor to avoid building the search request twice, here and then when actually executing the query
478+
minAndMax[i] = searchService.canMatch(buildShardSearchRequestForLocal(localNodeRequest, shards.get(i)))
479+
.estimatedMinAndMax();
477480
}
481+
478482
try {
479-
int[] indexes = CanMatchPreFilterSearchPhase.sortShards(
480-
localNodeRequest.shards,
483+
final int[] indexes = CanMatchPreFilterSearchPhase.sortShards(
484+
shards,
481485
minAndMax,
482486
FieldSortBuilder.getPrimaryFieldSortOrNull(request.source()).order()
483487
);
488+
final ShardToQuery[] orig = shards.toArray(new ShardToQuery[0]);
484489
for (int i = 0; i < indexes.length; i++) {
485-
ShardToQuery shardToQuery = localNodeRequest.shards.get(i);
486-
shardToQuery = localNodeRequest.shards.set(i, shardToQuery);
487-
localNodeRequest.shards.set(i, shardToQuery);
490+
shards.set(i, orig[indexes[i]]);
488491
}
489492
} catch (Exception e) {
490493
// ignored, field type conflicts will be dealt with in upstream logic
491494
// TODO: we should fail the query here, we're already seeing a field type conflict on the sort field,
492495
// no need to actually execute the queries and go through a lot of work before we inevitably have to
493496
// fail the search
497+
494498
}
495499
}
496500
executeWithoutBatching(localTarget, localNodeRequest);
@@ -650,14 +654,21 @@ static void registerNodeSearchAction(
650654
final SearchRequest searchRequest = request.searchRequest;
651655
final IntUnaryOperator shards;
652656
final ShardSearchRequest[] shardSearchRequests;
653-
if (hasPrimaryFieldSort(searchRequest.source())) {
654-
shardSearchRequests = new ShardSearchRequest[request.shards.size()];
657+
final int shardCount = request.shards.size();
658+
if (shardCount > 1 && hasPrimaryFieldSort(searchRequest.source())) {
659+
shardSearchRequests = new ShardSearchRequest[shardCount];
655660
@SuppressWarnings("rawtypes")
656-
final MinAndMax[] minAndMax = new MinAndMax[request.shards.size()];
661+
final MinAndMax[] minAndMax = new MinAndMax[shardCount];
657662
for (int i = 0; i < minAndMax.length; i++) {
658663
ShardSearchRequest r = buildShardSearchRequestForLocal(request, request.shards.get(i));
659664
shardSearchRequests[i] = r;
660-
minAndMax[i] = searchService.canMatch(r).estimatedMinAndMax();
665+
var canMatch = searchService.canMatch(r);
666+
if (canMatch.canMatch()) {
667+
r.setRunCanMatchInQueryPhase(false);
668+
minAndMax[i] = canMatch.estimatedMinAndMax();
669+
} else {
670+
assert false;
671+
}
661672
}
662673
int[] indexes = CanMatchPreFilterSearchPhase.sortShards(
663674
request.shards,
@@ -670,11 +681,10 @@ static void registerNodeSearchAction(
670681
shards = IntUnaryOperator.identity();
671682
}
672683
final CancellableTask cancellableTask = (CancellableTask) task;
673-
final int shardCount = request.shards.size();
674-
int workers = Math.min(request.searchRequest.getMaxConcurrentShardRequests(), Math.min(shardCount, searchPoolMax));
684+
int workers = Math.min(searchRequest.getMaxConcurrentShardRequests(), Math.min(shardCount, searchPoolMax));
675685
final var state = new QueryPerNodeState(
676686
new QueryPhaseResultConsumer(
677-
request.searchRequest,
687+
searchRequest,
678688
dependencies.executor,
679689
searchService.getCircuitBreaker(),
680690
searchPhaseController,

server/src/main/java/org/elasticsearch/search/SearchService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ public void executeQueryPhase(ShardSearchRequest request, CancellableTask task,
685685
threadPool
686686
).delegateFailure((l, orig) -> {
687687
// check if we can shortcut the query phase entirely.
688-
if (orig.canReturnNullResponseIfMatchNoDocs()) {
688+
if (orig.canReturnNullResponseIfMatchNoDocs() && orig.runCanMatchInQueryPhase()) {
689689
assert orig.scroll() == null;
690690
ShardSearchRequest clone = new ShardSearchRequest(orig);
691691
CanMatchContext canMatchContext = new CanMatchContext(

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ public class ShardSearchRequest extends AbstractTransportRequest implements Indi
101101
*/
102102
private final boolean forceSyntheticSource;
103103

104+
private transient boolean runCanMatchInQueryPhase = true;
105+
104106
public ShardSearchRequest(
105107
OriginalIndices originalIndices,
106108
SearchRequest searchRequest,
@@ -349,6 +351,14 @@ public void writeTo(StreamOutput out) throws IOException {
349351
OriginalIndices.writeOriginalIndices(originalIndices, out);
350352
}
351353

354+
public void setRunCanMatchInQueryPhase(boolean runCanMatchInQueryPhase) {
355+
this.runCanMatchInQueryPhase = runCanMatchInQueryPhase;
356+
}
357+
358+
public boolean runCanMatchInQueryPhase() {
359+
return runCanMatchInQueryPhase;
360+
}
361+
352362
protected final void innerWriteTo(StreamOutput out, boolean asKey) throws IOException {
353363
shardId.writeTo(out);
354364
out.writeByte(searchType.id());

0 commit comments

Comments
 (0)