@Override
 public <T> Page<T> scroll(String scrollId, long scrollTimeInMillis, Class<T> clazz) {
   SearchResponse response =
       client
           .prepareSearchScroll(scrollId)
           .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis))
           .execute()
           .actionGet();
   return resultsMapper.mapResults(response, clazz, null);
 }
  private IndexRequestBuilder prepareIndex(IndexQuery query) {
    try {
      String indexName =
          isBlank(query.getIndexName())
              ? retrieveIndexNameFromPersistentEntity(query.getObject().getClass())[0]
              : query.getIndexName();
      String type =
          isBlank(query.getType())
              ? retrieveTypeFromPersistentEntity(query.getObject().getClass())[0]
              : query.getType();

      IndexRequestBuilder indexRequestBuilder = null;

      if (query.getObject() != null) {
        String entityId = null;
        if (isDocument(query.getObject().getClass())) {
          entityId = getPersistentEntityId(query.getObject());
        }
        // If we have a query id and a document id, do not ask ES to generate one.
        if (query.getId() != null && entityId != null) {
          indexRequestBuilder = client.prepareIndex(indexName, type, query.getId());
        } else {
          indexRequestBuilder = client.prepareIndex(indexName, type);
        }
        indexRequestBuilder.setSource(
            resultsMapper.getEntityMapper().mapToString(query.getObject()));
      } else if (query.getSource() != null) {
        indexRequestBuilder =
            client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource());
      } else {
        throw new ElasticsearchException(
            "object or source is null, failed to index the document [id: " + query.getId() + "]");
      }
      if (query.getVersion() != null) {
        indexRequestBuilder.setVersion(query.getVersion());
        indexRequestBuilder.setVersionType(EXTERNAL);
      }

      if (query.getParentId() != null) {
        indexRequestBuilder.setParent(query.getParentId());
      }

      return indexRequestBuilder;
    } catch (IOException e) {
      throw new ElasticsearchException(
          "failed to index the document [id: " + query.getId() + "]", e);
    }
  }
  @Override
  public <T> Page<T> queryForPage(CriteriaQuery criteriaQuery, Class<T> clazz) {
    QueryBuilder elasticsearchQuery =
        new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria());
    FilterBuilder elasticsearchFilter =
        new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria());
    SearchRequestBuilder searchRequestBuilder = prepareSearch(criteriaQuery, clazz);

    if (elasticsearchQuery != null) {
      searchRequestBuilder.setQuery(elasticsearchQuery);
    } else {
      searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
    }

    if (criteriaQuery.getMinScore() > 0) {
      searchRequestBuilder.setMinScore(criteriaQuery.getMinScore());
    }

    if (elasticsearchFilter != null) searchRequestBuilder.setPostFilter(elasticsearchFilter);

    SearchResponse response = searchRequestBuilder.execute().actionGet();
    return resultsMapper.mapResults(response, clazz, criteriaQuery.getPageable());
  }
  @Override
  public <T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz) {
    int startRecord = 0;
    ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz);
    String indexName =
        isNotBlank(query.getIndexName()) ? query.getIndexName() : persistentEntity.getIndexName();
    String type = isNotBlank(query.getType()) ? query.getType() : persistentEntity.getIndexType();

    Assert.notNull(indexName, "No 'indexName' defined for MoreLikeThisQuery");
    Assert.notNull(type, "No 'type' defined for MoreLikeThisQuery");
    Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery");

    MoreLikeThisRequestBuilder requestBuilder =
        client.prepareMoreLikeThis(indexName, type, query.getId());

    if (query.getPageable() != null) {
      startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
      requestBuilder.setSearchSize(query.getPageable().getPageSize());
    }
    requestBuilder.setSearchFrom(startRecord);

    if (isNotEmpty(query.getSearchIndices())) {
      requestBuilder.setSearchIndices(toArray(query.getSearchIndices()));
    }
    if (isNotEmpty(query.getSearchTypes())) {
      requestBuilder.setSearchTypes(toArray(query.getSearchTypes()));
    }
    if (isNotEmpty(query.getFields())) {
      requestBuilder.setField(toArray(query.getFields()));
    }
    if (isNotBlank(query.getRouting())) {
      requestBuilder.setRouting(query.getRouting());
    }
    if (query.getPercentTermsToMatch() != null) {
      requestBuilder.setPercentTermsToMatch(query.getPercentTermsToMatch());
    }
    if (query.getMinTermFreq() != null) {
      requestBuilder.setMinTermFreq(query.getMinTermFreq());
    }
    if (query.getMaxQueryTerms() != null) {
      requestBuilder.maxQueryTerms(query.getMaxQueryTerms());
    }
    if (isNotEmpty(query.getStopWords())) {
      requestBuilder.setStopWords(toArray(query.getStopWords()));
    }
    if (query.getMinDocFreq() != null) {
      requestBuilder.setMinDocFreq(query.getMinDocFreq());
    }
    if (query.getMaxDocFreq() != null) {
      requestBuilder.setMaxDocFreq(query.getMaxDocFreq());
    }
    if (query.getMinWordLen() != null) {
      requestBuilder.setMinWordLen(query.getMinWordLen());
    }
    if (query.getMaxWordLen() != null) {
      requestBuilder.setMaxWordLen(query.getMaxWordLen());
    }
    if (query.getBoostTerms() != null) {
      requestBuilder.setBoostTerms(query.getBoostTerms());
    }

    SearchResponse response = requestBuilder.execute().actionGet();
    return resultsMapper.mapResults(response, clazz, query.getPageable());
  }
 @Override
 public <T> LinkedList<T> multiGet(SearchQuery searchQuery, Class<T> clazz) {
   return resultsMapper.mapResults(getMultiResponse(searchQuery, clazz), clazz);
 }