Server

[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를 사용하여 데이터를 가져옵니다.