@Override
  public void readFrom(StreamInput in) throws IOException {
    index = in.readUTF();
    shardId = in.readVInt();
    searchType = SearchType.fromId(in.readByte());
    numberOfShards = in.readVInt();
    if (in.readBoolean()) {
      scroll = readScroll(in);
    }

    source = in.readBytesReference();
    extraSource = in.readBytesReference();

    int typesSize = in.readVInt();
    if (typesSize > 0) {
      types = new String[typesSize];
      for (int i = 0; i < typesSize; i++) {
        types[i] = in.readUTF();
      }
    }
    int indicesSize = in.readVInt();
    if (indicesSize > 0) {
      filteringAliases = new String[indicesSize];
      for (int i = 0; i < indicesSize; i++) {
        filteringAliases[i] = in.readUTF();
      }
    } else {
      filteringAliases = null;
    }
    nowInMillis = in.readVLong();
  }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   out.writeUTF(index);
   out.writeVInt(shardId);
   out.writeByte(searchType.id());
   out.writeVInt(numberOfShards);
   if (scroll == null) {
     out.writeBoolean(false);
   } else {
     out.writeBoolean(true);
     scroll.writeTo(out);
   }
   out.writeBytesReference(source);
   out.writeBytesReference(extraSource);
   out.writeVInt(types.length);
   for (String type : types) {
     out.writeUTF(type);
   }
   if (filteringAliases != null) {
     out.writeVInt(filteringAliases.length);
     for (String index : filteringAliases) {
       out.writeUTF(index);
     }
   } else {
     out.writeVInt(0);
   }
   out.writeVLong(nowInMillis);
 }
  public void testDeepScrollingDoesNotBlowUp() throws Exception {
    client()
        .prepareIndex("index", "type", "1")
        .setSource("field", "value")
        .setRefresh(true)
        .execute()
        .get();

    for (SearchType searchType : SearchType.values()) {
      SearchRequestBuilder builder =
          client()
              .prepareSearch("index")
              .setSearchType(searchType)
              .setQuery(QueryBuilders.matchAllQuery())
              .setSize(Integer.MAX_VALUE)
              .setScroll("1m");

      SearchResponse response = builder.execute().actionGet();
      try {
        ElasticsearchAssertions.assertHitCount(response, 1l);
      } finally {
        String scrollId = response.getScrollId();
        if (scrollId != null) {
          clearScroll(scrollId);
        }
      }
    }
  }
 /**
  * Build a random search request.
  *
  * @param randomSearchSourceBuilder builds a random {@link SearchSourceBuilder}. You can use
  *     {@link #randomSearchSourceBuilder(Supplier, Supplier, Supplier, Supplier)}.
  */
 public static SearchRequest randomSearchRequest(
     Supplier<SearchSourceBuilder> randomSearchSourceBuilder) throws IOException {
   SearchRequest searchRequest = new SearchRequest();
   if (randomBoolean()) {
     searchRequest.indices(generateRandomStringArray(10, 10, false, false));
   }
   if (randomBoolean()) {
     searchRequest.indicesOptions(
         IndicesOptions.fromOptions(
             randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()));
   }
   if (randomBoolean()) {
     searchRequest.types(generateRandomStringArray(10, 10, false, false));
   }
   if (randomBoolean()) {
     searchRequest.preference(randomAsciiOfLengthBetween(3, 10));
   }
   if (randomBoolean()) {
     searchRequest.requestCache(randomBoolean());
   }
   if (randomBoolean()) {
     searchRequest.routing(randomAsciiOfLengthBetween(3, 10));
   }
   if (randomBoolean()) {
     searchRequest.scroll(randomPositiveTimeValue());
   }
   if (randomBoolean()) {
     searchRequest.searchType(randomFrom(SearchType.values()));
   }
   if (randomBoolean()) {
     searchRequest.source(randomSearchSourceBuilder.get());
   }
   return searchRequest;
 }
  public static SearchRequest parseSearchRequest(RestRequest request) {
    String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
    SearchRequest searchRequest = new SearchRequest(indices);
    // get the content, and put it in the body
    // add content/source as template if template flag is set
    boolean isTemplateRequest = request.path().endsWith("/template");
    if (RestActions.hasBodyContent(request)) {
      if (isTemplateRequest) {
        searchRequest.templateSource(RestActions.getRestContent(request));
      } else {
        searchRequest.source(RestActions.getRestContent(request));
      }
    }

    // do not allow 'query_and_fetch' or 'dfs_query_and_fetch' search types
    // from the REST layer. these modes are an internal optimization and should
    // not be specified explicitly by the user.
    String searchType = request.param("search_type");
    if (SearchType.fromString(searchType).equals(SearchType.QUERY_AND_FETCH)
        || SearchType.fromString(searchType).equals(SearchType.DFS_QUERY_AND_FETCH)) {
      throw new IllegalArgumentException("Unsupported search type [" + searchType + "]");
    } else {
      searchRequest.searchType(searchType);
    }

    searchRequest.extraSource(parseSearchSource(request));
    searchRequest.queryCache(request.paramAsBoolean("query_cache", null));

    String scroll = request.param("scroll");
    if (scroll != null) {
      searchRequest.scroll(new Scroll(parseTimeValue(scroll, null, "scroll")));
    }

    searchRequest.types(Strings.splitStringByCommaToArray(request.param("type")));
    searchRequest.routing(request.param("routing"));
    searchRequest.preference(request.param("preference"));
    searchRequest.indicesOptions(
        IndicesOptions.fromRequest(request, searchRequest.indicesOptions()));

    return searchRequest;
  }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   index = in.readUTF();
   shardId = in.readVInt();
   searchType = SearchType.fromId(in.readByte());
   numberOfShards = in.readVInt();
   if (in.readBoolean()) {
     scroll = readScroll(in);
   }
   if (in.readBoolean()) {
     timeout = readTimeValue(in);
   }
   sourceOffset = 0;
   sourceLength = in.readVInt();
   if (sourceLength == 0) {
     source = Bytes.EMPTY_ARRAY;
   } else {
     source = new byte[sourceLength];
     in.readFully(source);
   }
   extraSourceOffset = 0;
   extraSourceLength = in.readVInt();
   if (extraSourceLength == 0) {
     extraSource = Bytes.EMPTY_ARRAY;
   } else {
     extraSource = new byte[extraSourceLength];
     in.readFully(extraSource);
   }
   int typesSize = in.readVInt();
   if (typesSize > 0) {
     types = new String[typesSize];
     for (int i = 0; i < typesSize; i++) {
       types[i] = in.readUTF();
     }
   }
   int indicesSize = in.readVInt();
   if (indicesSize > 0) {
     filteringAliases = new String[indicesSize];
     for (int i = 0; i < indicesSize; i++) {
       filteringAliases[i] = in.readUTF();
     }
   } else {
     filteringAliases = null;
   }
   nowInMillis = in.readVLong();
 }
  private ElasticsearchQuery doCreateEsQuery(
      final Query query, final SearchRequest searchRequest, final QueryBuilder queryWithFilters) {
    final StorageSettings settings = searchRequest.getSettings();

    final ElasticsearchQuery.Builder queryBuilder =
        ElasticsearchQuery.create()
            .index(settings.getStorageName().getName())
            .indexType(settings.getStorageType().getName())
            .query(queryWithFilters)
            .setAggregations(aggregationsBuilder.create(query.getAggregationQueries()))
            .sortBuilders(sortBuilder.create(query.getOrderBys()))
            .filter(filterBuilderFactory.create(query.getPostFilters()))
            .setReturnFields(searchRequest.getReturnFields())
            .searchType(SearchType.valueOf(searchRequest.getSearchType().toString()))
            .from(query.getFrom())
            .size(query.getSize());

    return queryBuilder.build();
  }