/**
   * 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);
    }
  }