Backend · Infra

[ElasticSearch] Paging

devhyen 2024. 7. 22. 18:42
👑 목차 🎀
    반응형

    1. from 과 size 파라미터를 사용한 페이징

    •  from : 검색 결과의 시작점. 기본값은 0
    •  size : 한 번 검색 쿼리로 반환될 최대 문서 수. 기본값은 10 

    간단한 페이징을 위해 사용된다. 

    각 페이지마다 새로운 검색 요청을 보내야 한다.

    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.SearchHit;
    
    public class ElasticSearchPaging {
    
        public static void main(String[] args) throws Exception {
            // Elasticsearch 클라이언트 생성
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("localhost", 9200, "http")));
    
            // 인덱스와 검색 쿼리 정의
            String indexName = "your_index_name";
    
            // 페이징 설정
            int page = 1;
            int size = 10;
            int from = (page - 1) * size;
    
            // 검색 요청 생성
            SearchRequest searchRequest = new SearchRequest(indexName);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchAllQuery());
            searchSourceBuilder.from(from);
            searchSourceBuilder.size(size);
            searchRequest.source(searchSourceBuilder);
    
            // 검색 요청 실행
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    
            // 결과 출력
            for (SearchHit hit : searchResponse.getHits().getHits()) {
                System.out.println(hit.getSourceAsString());
            }
    
            // 클라이언트 종료
            client.close();
        }
    }

    2. scroll API

    scroll API는 대량의 데이터셋을 페이징 없이 효율적으로 가져올 수 있도록 설계되었다.

    scroll은 일종의 커서로 검색 컨텍스트를 유지하면서 데이터를 가져올 수 있게 한다.

     

    1.  초기 검색 요청을 실행하고 scroll_id를 얻는다.
    2.  scroll_id 를 사용하여 다음 데이터 블록을 요청한다.
    3.  모든 데이터를 다 가져올 때까지 반복한다.

     

    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.action.search.SearchScrollRequest;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.unit.TimeValue;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.Scroll;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.action.search.ClearScrollRequest;
    import org.elasticsearch.action.search.ClearScrollResponse;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ElasticSearchScrollPaging {
    
        public static void main(String[] args) throws Exception {
            // Elasticsearch 클라이언트 생성
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("localhost", 9200, "http")));
    
            // 인덱스와 검색 쿼리 정의
            String indexName = "your_index_name";
    
            // Scroll 객체 생성 (기본적으로 2분 동안 유효)
            final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(2));
            
            // 초기 scroll 요청 생성
            SearchRequest searchRequest = new SearchRequest(indexName);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchAllQuery());
            searchSourceBuilder.size(1000);  // 한 번에 가져올 문서 수
            searchRequest.source(searchSourceBuilder);
            searchRequest.scroll(scroll);
    
            // 초기 scroll 요청 실행
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            String scrollId = searchResponse.getScrollId();
            SearchHit[] searchHits = searchResponse.getHits().getHits();
    
            // 결과를 저장할 리스트
            List<String> allHits = new ArrayList<>();
    
            while (searchHits != null && searchHits.length > 0) {
                // 검색 결과 저장
                for (SearchHit hit : searchHits) {
                    allHits.add(hit.getSourceAsString());
                }
    
                // 다음 scroll 요청 생성
                SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
                scrollRequest.scroll(scroll);
                searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
                scrollId = searchResponse.getScrollId();
                searchHits = searchResponse.getHits().getHits();
            }
    
            // 결과 출력
            for (String hit : allHits) {
                System.out.println(hit);
            }
    
            // Scroll context를 종료
            ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
            clearScrollRequest.addScrollId(scrollId);
            ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
            boolean succeeded = clearScrollResponse.isSucceeded();
    
            // 클라이언트 종료
            client.close();
        }
    }

     

    대량의 데이터를 효율적으로 페이징하기 위해 사용됩니다.

    처음에 검색 컨텍스트를 만들고, 이후에는 scroll ID를 사용하여 데이터를 가져옵니다.

    반응형