public DefaultSearchContext(
     long id,
     ShardSearchRequest request,
     SearchShardTarget shardTarget,
     Engine.Searcher engineSearcher,
     IndexService indexService,
     IndexShard indexShard,
     ScriptService scriptService,
     PageCacheRecycler pageCacheRecycler,
     BigArrays bigArrays,
     Counter timeEstimateCounter,
     ParseFieldMatcher parseFieldMatcher,
     TimeValue timeout) {
   super(parseFieldMatcher, request);
   this.id = id;
   this.request = request;
   this.searchType = request.searchType();
   this.shardTarget = shardTarget;
   this.engineSearcher = engineSearcher;
   this.scriptService = scriptService;
   this.pageCacheRecycler = pageCacheRecycler;
   // SearchContexts use a BigArrays that can circuit break
   this.bigArrays = bigArrays.withCircuitBreaking();
   this.dfsResult = new DfsSearchResult(id, shardTarget);
   this.queryResult = new QuerySearchResult(id, shardTarget);
   this.fetchResult = new FetchSearchResult(id, shardTarget);
   this.indexShard = indexShard;
   this.indexService = indexService;
   this.searcher = new ContextIndexSearcher(this, engineSearcher);
   this.timeEstimateCounter = timeEstimateCounter;
   this.timeoutInMillis = timeout.millis();
 }
 @Override
 public SearchLookup lookup() {
   // TODO: The types should take into account the parsing context in QueryParserContext...
   if (searchLookup == null) {
     searchLookup = new SearchLookup(mapperService(), fieldData(), request.types());
   }
   return searchLookup;
 }
 @Override
 public ObjectMapper getObjectMapper(String name) {
   return mapperService().getObjectMapper(name, request.types());
 }
 @Override
 public MappedFieldType smartNameFieldType(String name) {
   return mapperService().smartNameFieldType(name, request.types());
 }
 @Override
 protected long nowInMillisImpl() {
   return request.nowInMillis();
 }
 @Override
 public String[] types() {
   return request.types();
 }
 @Override
 public boolean hasTypes() {
   return request.types() != null && request.types().length > 0;
 }
 @Override
 public int numberOfShards() {
   return request.numberOfShards();
 }
  /**
   * Should be called before executing the main query and after all other parameters have been set.
   */
  @Override
  public void preProcess() {
    if (scrollContext == null) {
      long from = from() == -1 ? 0 : from();
      long size = size() == -1 ? 10 : size();
      long resultWindow = from + size;
      // We need settingsService's view of the settings because its dynamic.
      // indexService's isn't.
      int maxResultWindow =
          indexService
              .getIndexSettings()
              .getSettings()
              .getAsInt(MAX_RESULT_WINDOW, Defaults.MAX_RESULT_WINDOW);

      if (resultWindow > maxResultWindow) {
        throw new QueryPhaseExecutionException(
            this,
            "Result window is too large, from + size must be less than or equal to: ["
                + maxResultWindow
                + "] but was ["
                + resultWindow
                + "]. See the scroll api for a more efficient way to request large data sets. "
                + "This limit can be set by changing the ["
                + DefaultSearchContext.MAX_RESULT_WINDOW
                + "] index level parameter.");
      }
    }

    // initialize the filtering alias based on the provided filters
    aliasFilter =
        indexService.aliasFilter(indexShard.getQueryShardContext(), request.filteringAliases());

    if (query() == null) {
      parsedQuery(ParsedQuery.parsedMatchAllQuery());
    }
    if (queryBoost() != AbstractQueryBuilder.DEFAULT_BOOST) {
      parsedQuery(
          new ParsedQuery(
              new FunctionScoreQuery(query(), new WeightFactorFunction(queryBoost)),
              parsedQuery()));
    }
    Query searchFilter = searchFilter(types());
    if (searchFilter != null) {
      if (Queries.isConstantMatchAllQuery(query())) {
        Query q = new ConstantScoreQuery(searchFilter);
        if (query().getBoost() != AbstractQueryBuilder.DEFAULT_BOOST) {
          q = new BoostQuery(q, query().getBoost());
        }
        parsedQuery(new ParsedQuery(q, parsedQuery()));
      } else {
        BooleanQuery filtered =
            new BooleanQuery.Builder()
                .add(query(), Occur.MUST)
                .add(searchFilter, Occur.FILTER)
                .build();
        parsedQuery(new ParsedQuery(filtered, parsedQuery()));
      }
    }
    try {
      this.query = searcher().rewrite(this.query);
    } catch (IOException e) {
      throw new QueryPhaseExecutionException(this, "Failed to rewrite main query", e);
    }
  }