Java ElasticSearch implementation for window size more than 10k

Java ElasticSearch implementation with search_after feature



12/27/20232 min read


Implementing search functionality using Spring Boot and Elasticsearch with the "search_after" feature involves a few steps. The "search_after" feature is used for efficient pagination of search results. It is often used in conjunction with sorting to navigate through large result sets.

Here's a basic guide on how you can implement this in a Spring Boot application:

  1. Add Dependencies:

    Ensure that you have the necessary dependencies in your pom.xml file:


    <!-- Other dependencies -->






  2. Configure Elasticsearch: Configure Elasticsearch properties in your or application.yml file:

    Adjust these properties based on your Elasticsearch configuration.

  3. Create an Entity: Create an entity class representing your data model. Annotate it with @Document to mark it as an Elasticsearch document.



    @Document(indexName = "your_index_name", type = "your_type")

    public class YourEntity {


    private String id;

    // Other fields, getters, and setters


  4. Repository Interface: Create a repository interface that extends ElasticsearchRepository:


    public interface YourEntityRepository extends ElasticsearchRepository<YourEntity, String> {

    // Custom query methods if needed


  5. Service Class: Create a service class where you can implement the logic for searching with "search_after":


    import org.springframework.beans.factory.annotation.Autowired;






    import org.springframework.stereotype.Service;

    import java.util.List;


    public class YourEntityService {


    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    private YourEntityRepository repository;

    public List<YourEntity> searchWithSearchAfter(String searchAfterValue, int pageSize) {

    SearchQuery searchQuery = new NativeSearchQueryBuilder()

    .withQuery(/* your query criteria here */)

    .withSort(/* your sorting criteria here */)

    .withPageable(/* use PageRequest.of(0, pageSize) for the first page */)

    .withSearchAfter(searchAfterValue) // Set the search_after value


    return, YourEntity.class,

    new SearchHitCallback<YourEntity>() {


    public List<YourEntity> doWithSearchHits(SearchHit<YourEntity> searchHit) {

    // Extract and return the list of entities

    return List.of(searchHit.getContent());





    Customize the withQuery, withSort, and other methods in NativeSearchQueryBuilder based on your search requirements.

  6. Controller: Create a controller to expose the search functionality:

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.web.bind.annotation.GetMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.bind.annotation.RestController;

    import java.util.List;


    public class YourEntityController {


    private YourEntityService service;


    public List<YourEntity> searchWithSearchAfter(@RequestParam String searchAfterValue, @RequestParam int pageSize) {

    return service.searchWithSearchAfter(searchAfterValue, pageSize);



    This controller endpoint can be called with the searchAfterValue and pageSize parameters to retrieve the next set of results.

Remember to adapt these examples according to your specific requirements and use case. The provided code serves as a starting point, and you may need to make adjustments based on your application's needs.