Fix bug in single shard optimization when sorting documents in search request
This commit adds a function to shard-level query result to determine whether there are any hits that needs fetching. Currently, a shard-level query result can have hits when there are search hits and/or completion suggestion hits. The newly added function encapsulates the checks to determine if a shard-level query result has any fetchable hits, which is used in optimizing for sorting documents and releasing search request contexts.
This commit is contained in:
parent
7542ef3173
commit
40d7ebc515
|
@ -322,11 +322,8 @@ abstract class AbstractSearchAsyncAction<FirstResult extends SearchPhaseResult>
|
|||
// we only release search context that we did not fetch from if we are not scrolling
|
||||
if (request.scroll() == null) {
|
||||
for (AtomicArray.Entry<? extends QuerySearchResultProvider> entry : queryResults.asList()) {
|
||||
QuerySearchResult queryResult = entry.value.queryResult().queryResult();
|
||||
final TopDocs topDocs = queryResult.topDocs();
|
||||
final Suggest suggest = queryResult.suggest();
|
||||
if (((topDocs != null && topDocs.scoreDocs.length > 0) // the shard had matches
|
||||
||suggest != null && suggest.hasScoreDocs()) // or had suggest docs
|
||||
QuerySearchResult queryResult = entry.value.queryResult();
|
||||
if (queryResult.hasHits()
|
||||
&& docIdsToLoad.get(entry.index) == null) { // but none of them made it to the global top docs
|
||||
try {
|
||||
DiscoveryNode node = nodes.get(entry.value.queryResult().shardTarget().nodeId());
|
||||
|
|
|
@ -269,7 +269,7 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv
|
|||
|
||||
loadOrExecuteQueryPhase(request, context);
|
||||
|
||||
if (hasHits(context.queryResult()) == false && context.scrollContext() == null) {
|
||||
if (context.queryResult().hasHits() == false && context.scrollContext() == null) {
|
||||
freeContext(context.id());
|
||||
} else {
|
||||
contextProcessedSuccessfully(context);
|
||||
|
@ -324,7 +324,7 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv
|
|||
operationListener.onPreQueryPhase(context);
|
||||
long time = System.nanoTime();
|
||||
queryPhase.execute(context);
|
||||
if (hasHits(context.queryResult()) == false && context.scrollContext() == null) {
|
||||
if (context.queryResult().hasHits() == false && context.scrollContext() == null) {
|
||||
// no hits, we can release the context since there will be no fetch phase
|
||||
freeContext(context.id());
|
||||
} else {
|
||||
|
@ -861,11 +861,6 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv
|
|||
context.docIdsToLoad(docIdsToLoad, 0, docIdsToLoad.length);
|
||||
}
|
||||
|
||||
private static boolean hasHits(final QuerySearchResult searchResult) {
|
||||
return searchResult.topDocs().scoreDocs.length > 0 ||
|
||||
(searchResult.suggest() != null && searchResult.suggest().hasScoreDocs());
|
||||
}
|
||||
|
||||
private void processScroll(InternalScrollSearchRequest request, SearchContext context) {
|
||||
// process scroll
|
||||
context.from(context.from() + context.size());
|
||||
|
|
|
@ -181,7 +181,7 @@ public class SearchPhaseController extends AbstractComponent {
|
|||
} else {
|
||||
// lets see if we only got hits from a single shard, if so, we can optimize...
|
||||
for (AtomicArray.Entry<? extends QuerySearchResultProvider> entry : results) {
|
||||
if (entry.value.queryResult().topDocs().scoreDocs.length > 0) {
|
||||
if (entry.value.queryResult().hasHits()) {
|
||||
if (result != null) { // we already have one, can't really optimize
|
||||
canOptimize = false;
|
||||
break;
|
||||
|
|
|
@ -188,6 +188,12 @@ public class QuerySearchResult extends QuerySearchResultProvider {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Returns true iff the result has hits */
|
||||
public boolean hasHits() {
|
||||
return (topDocs != null && topDocs.scoreDocs.length > 0) ||
|
||||
(suggest != null && suggest.hasScoreDocs());
|
||||
}
|
||||
|
||||
public static QuerySearchResult readQuerySearchResult(StreamInput in) throws IOException {
|
||||
QuerySearchResult result = new QuerySearchResult();
|
||||
result.readFrom(in);
|
||||
|
|
Loading…
Reference in New Issue