|
65 | 65 | import java.util.Map;
|
66 | 66 | import java.util.function.Function;
|
67 | 67 | import java.util.function.IntFunction;
|
| 68 | +import java.util.stream.Collectors; |
68 | 69 |
|
69 | 70 | public final class SearchPhaseController {
|
70 | 71 |
|
@@ -427,6 +428,15 @@ private ReducedQueryPhase reducedQueryPhase(Collection<? extends SearchPhaseResu
|
427 | 428 | return new ReducedQueryPhase(totalHits, topDocsStats.fetchHits, topDocsStats.getMaxScore(),
|
428 | 429 | false, null, null, null, null, SortedTopDocs.EMPTY, null, numReducePhases, 0, 0, true);
|
429 | 430 | }
|
| 431 | + int total = queryResults.size(); |
| 432 | + queryResults = queryResults.stream() |
| 433 | + .filter(res -> res.queryResult().isNull() == false) |
| 434 | + .collect(Collectors.toList()); |
| 435 | + String errorMsg = "must have at least one non-empty search result, got 0 out of " + total; |
| 436 | + assert queryResults.isEmpty() == false : errorMsg; |
| 437 | + if (queryResults.isEmpty()) { |
| 438 | + throw new IllegalStateException(errorMsg); |
| 439 | + } |
430 | 440 | final QuerySearchResult firstResult = queryResults.stream().findFirst().get().queryResult();
|
431 | 441 | final boolean hasSuggest = firstResult.suggest() != null;
|
432 | 442 | final boolean hasProfileResults = firstResult.hasProfileResults();
|
@@ -622,36 +632,38 @@ public void consumeResult(SearchPhaseResult result) {
|
622 | 632 | }
|
623 | 633 |
|
624 | 634 | private synchronized void consumeInternal(QuerySearchResult querySearchResult) {
|
625 |
| - if (index == bufferSize) { |
| 635 | + if (querySearchResult.isNull() == false) { |
| 636 | + if (index == bufferSize) { |
| 637 | + if (hasAggs) { |
| 638 | + ReduceContext reduceContext = controller.reduceContextFunction.apply(false); |
| 639 | + InternalAggregations reducedAggs = InternalAggregations.topLevelReduce(Arrays.asList(aggsBuffer), reduceContext); |
| 640 | + Arrays.fill(aggsBuffer, null); |
| 641 | + aggsBuffer[0] = reducedAggs; |
| 642 | + } |
| 643 | + if (hasTopDocs) { |
| 644 | + TopDocs reducedTopDocs = mergeTopDocs(Arrays.asList(topDocsBuffer), |
| 645 | + // we have to merge here in the same way we collect on a shard |
| 646 | + querySearchResult.from() + querySearchResult.size(), 0); |
| 647 | + Arrays.fill(topDocsBuffer, null); |
| 648 | + topDocsBuffer[0] = reducedTopDocs; |
| 649 | + } |
| 650 | + numReducePhases++; |
| 651 | + index = 1; |
| 652 | + if (hasAggs) { |
| 653 | + progressListener.notifyPartialReduce(progressListener.searchShards(processedShards), |
| 654 | + topDocsStats.getTotalHits(), aggsBuffer[0], numReducePhases); |
| 655 | + } |
| 656 | + } |
| 657 | + final int i = index++; |
626 | 658 | if (hasAggs) {
|
627 |
| - ReduceContext reduceContext = controller.reduceContextFunction.apply(false); |
628 |
| - InternalAggregations reducedAggs = InternalAggregations.topLevelReduce(Arrays.asList(aggsBuffer), reduceContext); |
629 |
| - Arrays.fill(aggsBuffer, null); |
630 |
| - aggsBuffer[0] = reducedAggs; |
| 659 | + aggsBuffer[i] = (InternalAggregations) querySearchResult.consumeAggs(); |
631 | 660 | }
|
632 | 661 | if (hasTopDocs) {
|
633 |
| - TopDocs reducedTopDocs = mergeTopDocs(Arrays.asList(topDocsBuffer), |
634 |
| - // we have to merge here in the same way we collect on a shard |
635 |
| - querySearchResult.from() + querySearchResult.size(), 0); |
636 |
| - Arrays.fill(topDocsBuffer, null); |
637 |
| - topDocsBuffer[0] = reducedTopDocs; |
| 662 | + final TopDocsAndMaxScore topDocs = querySearchResult.consumeTopDocs(); // can't be null |
| 663 | + topDocsStats.add(topDocs, querySearchResult.searchTimedOut(), querySearchResult.terminatedEarly()); |
| 664 | + setShardIndex(topDocs.topDocs, querySearchResult.getShardIndex()); |
| 665 | + topDocsBuffer[i] = topDocs.topDocs; |
638 | 666 | }
|
639 |
| - numReducePhases++; |
640 |
| - index = 1; |
641 |
| - if (hasAggs) { |
642 |
| - progressListener.notifyPartialReduce(progressListener.searchShards(processedShards), |
643 |
| - topDocsStats.getTotalHits(), aggsBuffer[0], numReducePhases); |
644 |
| - } |
645 |
| - } |
646 |
| - final int i = index++; |
647 |
| - if (hasAggs) { |
648 |
| - aggsBuffer[i] = (InternalAggregations) querySearchResult.consumeAggs(); |
649 |
| - } |
650 |
| - if (hasTopDocs) { |
651 |
| - final TopDocsAndMaxScore topDocs = querySearchResult.consumeTopDocs(); // can't be null |
652 |
| - topDocsStats.add(topDocs, querySearchResult.searchTimedOut(), querySearchResult.terminatedEarly()); |
653 |
| - setShardIndex(topDocs.topDocs, querySearchResult.getShardIndex()); |
654 |
| - topDocsBuffer[i] = topDocs.topDocs; |
655 | 667 | }
|
656 | 668 | processedShards[querySearchResult.getShardIndex()] = querySearchResult.getSearchShardTarget();
|
657 | 669 | }
|
@@ -731,7 +743,7 @@ ReducedQueryPhase reduce() {
|
731 | 743 |
|
732 | 744 | static final class TopDocsStats {
|
733 | 745 | final int trackTotalHitsUpTo;
|
734 |
| - private long totalHits; |
| 746 | + long totalHits; |
735 | 747 | private TotalHits.Relation totalHitsRelation;
|
736 | 748 | long fetchHits;
|
737 | 749 | private float maxScore = Float.NEGATIVE_INFINITY;
|
|
0 commit comments