@Test
  public void shouldSortResultsGivenSortCriteria() {
    // given
    List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
    // first document
    String documentId = randomNumeric(5);
    SampleEntity sampleEntity1 = new SampleEntity();
    sampleEntity1.setId(documentId);
    sampleEntity1.setMessage("abc");
    sampleEntity1.setRate(10);
    sampleEntity1.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery1 = new IndexQuery();
    indexQuery1.setId(documentId);
    indexQuery1.setObject(sampleEntity1);

    // second document
    String documentId2 = randomNumeric(5);
    SampleEntity sampleEntity2 = new SampleEntity();
    sampleEntity2.setId(documentId2);
    sampleEntity2.setMessage("xyz");
    sampleEntity2.setRate(5);
    sampleEntity2.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery2 = new IndexQuery();
    indexQuery2.setId(documentId2);
    indexQuery2.setObject(sampleEntity2);

    // third document
    String documentId3 = randomNumeric(5);
    SampleEntity sampleEntity3 = new SampleEntity();
    sampleEntity3.setId(documentId3);
    sampleEntity3.setMessage("xyz");
    sampleEntity3.setRate(15);
    sampleEntity3.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery3 = new IndexQuery();
    indexQuery3.setId(documentId3);
    indexQuery3.setObject(sampleEntity3);

    indexQueries.add(indexQuery1);
    indexQueries.add(indexQuery2);
    indexQueries.add(indexQuery3);

    elasticsearchTemplate.bulkIndex(indexQueries);
    elasticsearchTemplate.refresh(SampleEntity.class, true);

    SearchQuery searchQuery =
        new NativeSearchQueryBuilder()
            .withQuery(matchAllQuery())
            .withSort(new FieldSortBuilder("rate").ignoreUnmapped(true).order(SortOrder.ASC))
            .build();
    // when
    Page<SampleEntity> sampleEntities =
        elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
    // then
    assertThat(sampleEntities.getTotalElements(), equalTo(3L));
    assertThat(sampleEntities.getContent().get(0).getRate(), is(sampleEntity2.getRate()));
  }
  @Test
  public void shouldReturnListForGivenCriteria() {
    // given
    List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
    // first document
    String documentId = randomNumeric(5);
    SampleEntity sampleEntity1 = new SampleEntity();
    sampleEntity1.setId(documentId);
    sampleEntity1.setMessage("test message");
    sampleEntity1.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery1 = new IndexQuery();
    indexQuery1.setId(documentId);
    indexQuery1.setObject(sampleEntity1);
    indexQueries.add(indexQuery1);

    // second document
    String documentId2 = randomNumeric(5);
    SampleEntity sampleEntity2 = new SampleEntity();
    sampleEntity2.setId(documentId2);
    sampleEntity2.setMessage("test test");
    sampleEntity2.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery2 = new IndexQuery();
    indexQuery2.setId(documentId2);
    indexQuery2.setObject(sampleEntity2);

    indexQueries.add(indexQuery2);

    // second document
    String documentId3 = randomNumeric(5);
    SampleEntity sampleEntity3 = new SampleEntity();
    sampleEntity3.setId(documentId3);
    sampleEntity3.setMessage("some message");
    sampleEntity3.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery3 = new IndexQuery();
    indexQuery3.setId(documentId3);
    indexQuery3.setObject(sampleEntity3);

    indexQueries.add(indexQuery3);
    // when
    elasticsearchTemplate.bulkIndex(indexQueries);
    elasticsearchTemplate.refresh(SampleEntity.class, true);
    // when
    CriteriaQuery singleCriteriaQuery = new CriteriaQuery(new Criteria("message").contains("test"));
    CriteriaQuery multipleCriteriaQuery =
        new CriteriaQuery(
            new Criteria("message").contains("some").and("message").contains("message"));
    List<SampleEntity> sampleEntitiesForSingleCriteria =
        elasticsearchTemplate.queryForList(singleCriteriaQuery, SampleEntity.class);
    List<SampleEntity> sampleEntitiesForAndCriteria =
        elasticsearchTemplate.queryForList(multipleCriteriaQuery, SampleEntity.class);
    // then
    assertThat(sampleEntitiesForSingleCriteria.size(), is(2));
    assertThat(sampleEntitiesForAndCriteria.size(), is(1));
  }
  @Test
  public void shouldReturnResultsWithScanAndScroll() {
    // given
    List<IndexQuery> entities = createSampleEntitiesWithMessage("Test message", 30);
    // when
    elasticsearchTemplate.bulkIndex(entities);
    elasticsearchTemplate.refresh(SampleEntity.class, true);
    // then

    SearchQuery searchQuery =
        new NativeSearchQueryBuilder()
            .withQuery(matchAllQuery())
            .withIndices("test-index")
            .withTypes("test-type")
            .withPageable(new PageRequest(0, 10))
            .build();

    String scrollId = elasticsearchTemplate.scan(searchQuery, 1000, false);
    List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
    boolean hasRecords = true;
    while (hasRecords) {
      Page<SampleEntity> page =
          elasticsearchTemplate.scroll(
              scrollId,
              5000L,
              new ResultsMapper<SampleEntity>() {
                @Override
                public FacetedPage<SampleEntity> mapResults(SearchResponse response) {
                  List<SampleEntity> chunk = new ArrayList<SampleEntity>();
                  for (SearchHit searchHit : response.getHits()) {
                    if (response.getHits().getHits().length <= 0) {
                      return null;
                    }
                    SampleEntity user = new SampleEntity();
                    user.setId(searchHit.getId());
                    user.setMessage((String) searchHit.getSource().get("message"));
                    chunk.add(user);
                  }
                  if (chunk.size() > 0) {

                    return new FacetedPageImpl<SampleEntity>(chunk);
                  }
                  return null;
                }
              });
      if (page != null) {
        sampleEntities.addAll(page.getContent());
      } else {
        hasRecords = false;
      }
    }
    assertThat(sampleEntities.size(), is(equalTo(30)));
  }
  @Test
  public void shouldReturnListForGivenStringQuery() {
    // given
    List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
    // first document
    String documentId = randomNumeric(5);
    SampleEntity sampleEntity1 = new SampleEntity();
    sampleEntity1.setId(documentId);
    sampleEntity1.setMessage("test message");
    sampleEntity1.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery1 = new IndexQuery();
    indexQuery1.setId(documentId);
    indexQuery1.setObject(sampleEntity1);
    indexQueries.add(indexQuery1);

    // second document
    String documentId2 = randomNumeric(5);
    SampleEntity sampleEntity2 = new SampleEntity();
    sampleEntity2.setId(documentId2);
    sampleEntity2.setMessage("test test");
    sampleEntity2.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery2 = new IndexQuery();
    indexQuery2.setId(documentId2);
    indexQuery2.setObject(sampleEntity2);

    indexQueries.add(indexQuery2);

    // second document
    String documentId3 = randomNumeric(5);
    SampleEntity sampleEntity3 = new SampleEntity();
    sampleEntity3.setId(documentId3);
    sampleEntity3.setMessage("some message");
    sampleEntity3.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery3 = new IndexQuery();
    indexQuery3.setId(documentId3);
    indexQuery3.setObject(sampleEntity3);

    indexQueries.add(indexQuery3);
    // when
    elasticsearchTemplate.bulkIndex(indexQueries);
    elasticsearchTemplate.refresh(SampleEntity.class, true);
    // when
    StringQuery stringQuery = new StringQuery(matchAllQuery().toString());
    List<SampleEntity> sampleEntities =
        elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class);
    // then
    assertThat(sampleEntities.size(), is(3));
  }
  @Test
  public void shouldDoBulkIndex() {
    // given
    List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
    // first document
    String documentId = randomNumeric(5);
    SampleEntity sampleEntity1 = new SampleEntity();
    sampleEntity1.setId(documentId);
    sampleEntity1.setMessage("some message");
    sampleEntity1.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery1 = new IndexQuery();
    indexQuery1.setId(documentId);
    indexQuery1.setObject(sampleEntity1);
    indexQueries.add(indexQuery1);

    // second document
    String documentId2 = randomNumeric(5);
    SampleEntity sampleEntity2 = new SampleEntity();
    sampleEntity2.setId(documentId2);
    sampleEntity2.setMessage("some message");
    sampleEntity2.setVersion(System.currentTimeMillis());

    IndexQuery indexQuery2 = new IndexQuery();
    indexQuery2.setId(documentId2);
    indexQuery2.setObject(sampleEntity2);

    indexQueries.add(indexQuery2);
    // when
    elasticsearchTemplate.bulkIndex(indexQueries);
    elasticsearchTemplate.refresh(SampleEntity.class, true);
    // then
    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
    Page<SampleEntity> sampleEntities =
        elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
    assertThat(sampleEntities.getTotalElements(), is(equalTo(2L)));
  }