public QueryFetchSearchResult executeFetchPhase(QuerySearchRequest request) {
   final SearchContext context = findContext(request.id());
   contextProcessing(context);
   try {
     final IndexCache indexCache = context.indexShard().indexService().cache();
     context
         .searcher()
         .dfSource(
             new CachedDfSource(
                 context.searcher().getIndexReader(),
                 request.dfs(),
                 context.similarityService().similarity(),
                 indexCache.filter(),
                 indexCache.filterPolicy()));
   } catch (Throwable e) {
     freeContext(context.id());
     cleanContext(context);
     throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
   }
   try {
     ShardSearchStats shardSearchStats = context.indexShard().searchService();
     shardSearchStats.onPreQueryPhase(context);
     long time = System.nanoTime();
     try {
       queryPhase.execute(context);
     } catch (Throwable e) {
       shardSearchStats.onFailedQueryPhase(context);
       throw ExceptionsHelper.convertToRuntime(e);
     }
     long time2 = System.nanoTime();
     shardSearchStats.onQueryPhase(context, time2 - time);
     shardSearchStats.onPreFetchPhase(context);
     try {
       shortcutDocIdsToLoad(context);
       fetchPhase.execute(context);
       if (context.scroll() == null) {
         freeContext(request.id());
       } else {
         contextProcessedSuccessfully(context);
       }
     } catch (Throwable e) {
       shardSearchStats.onFailedFetchPhase(context);
       throw ExceptionsHelper.convertToRuntime(e);
     }
     shardSearchStats.onFetchPhase(context, System.nanoTime() - time2);
     return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
   } catch (Throwable e) {
     logger.trace("Fetch phase failed", e);
     processFailure(context, e);
     throw ExceptionsHelper.convertToRuntime(e);
   } finally {
     cleanContext(context);
   }
 }
 public QuerySearchResult executeQueryPhase(QuerySearchRequest request) {
   final SearchContext context = findContext(request.id());
   contextProcessing(context);
   try {
     final IndexCache indexCache = context.indexShard().indexService().cache();
     context
         .searcher()
         .dfSource(
             new CachedDfSource(
                 context.searcher().getIndexReader(),
                 request.dfs(),
                 context.similarityService().similarity(),
                 indexCache.filter(),
                 indexCache.filterPolicy()));
   } catch (Throwable e) {
     processFailure(context, e);
     cleanContext(context);
     throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
   }
   ShardSearchStats shardSearchStats = context.indexShard().searchService();
   try {
     shardSearchStats.onPreQueryPhase(context);
     long time = System.nanoTime();
     queryPhase.execute(context);
     if (context.queryResult().topDocs().scoreDocs.length == 0 && context.scroll() == null) {
       // no hits, we can release the context since there will be no fetch phase
       freeContext(context.id());
     } else {
       contextProcessedSuccessfully(context);
     }
     shardSearchStats.onQueryPhase(context, System.nanoTime() - time);
     return context.queryResult();
   } catch (Throwable e) {
     shardSearchStats.onFailedQueryPhase(context);
     logger.trace("Query phase failed", e);
     processFailure(context, e);
     throw ExceptionsHelper.convertToRuntime(e);
   } finally {
     cleanContext(context);
   }
 }