기술과 산업/언어 및 프레임워크

Spring Boot 시리즈 36편 – Elasticsearch 연동: 검색 기능 확장을 위한 인덱싱, 매핑, 쿼리 전략

B컷개발자 2025. 5. 26. 10:49
728x90

Spring Boot에서 Elasticsearch를 연동하여 검색 기능을 구현하는 방법을 설명합니다. 인덱스 설계, 매핑 구조, 쿼리 작성, 운영 적용 전략까지 실무 중심으로 정리한 검색 시스템 구축 가이드입니다.

 

전통적인 RDB 기반 LIKE 검색은 유연성과 성능에 한계가 있습니다.
특히 전체 텍스트 검색이나 복합 조건 검색이 필요한 경우
Elasticsearch를 연동한 검색 전용 아키텍처가 필요한 이유입니다.

Spring Boot와 Elasticsearch를 연동하면

  • 도메인 객체를 기반으로 간결하게 인덱싱하고
  • 다양한 검색 쿼리를 조합할 수 있으며
  • 확장성과 응답 속도를 동시에 만족하는 검색 시스템을 구축할 수 있습니다.

1. Elasticsearch 기본 개념 정리

개념 설명

Index DB의 테이블과 유사, 검색 단위
Document 하나의 JSON 형식 데이터 객체
Field 문서 내 속성, RDB의 컬럼에 해당
Mapping 필드별 데이터 타입 정의
Query DSL Elasticsearch 전용 JSON 쿼리 문법

2. 의존성 추가

Gradle

implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'

Spring Boot 3.x 기준으로 Elasticsearch 8.x 이상 호환됨.
로컬 테스트용 Docker 예시:

docker run -d -p 9200:9200 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:8.11.3

3. Elasticsearch 설정

application.yml 예시

spring:
  data:
    elasticsearch:
      repositories:
        enabled: true
      cluster-nodes: localhost:9200
      username: elastic
      password: changeme

4. 도메인 매핑 및 Repository 구성

도메인 정의 예시

@Document(indexName = "products")
@Getter @Setter
public class Product {

    @Id
    private String id;

    @Field(type = FieldType.Text)
    private String name;

    @Field(type = FieldType.Text)
    private String description;

    @Field(type = FieldType.Keyword)
    private String category;

    @Field(type = FieldType.Double)
    private double price;
}

Repository 인터페이스

public interface ProductSearchRepository extends ElasticsearchRepository<Product, String> {

    List<Product> findByNameContaining(String keyword);

    List<Product> findByCategoryAndPriceBetween(String category, double min, double max);
}

→ Spring Data Elasticsearch는 JPA와 유사한 메서드 이름 기반 쿼리를 지원함


5. 서비스 및 API 구성

검색 API 예시

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/products")
public class ProductSearchController {

    private final ProductSearchRepository productSearchRepository;

    @GetMapping("/search")
    public List<Product> search(@RequestParam String keyword) {
        return productSearchRepository.findByNameContaining(keyword);
    }
}

6. 고급 쿼리 – QueryBuilders 사용

복합 조건 검색 시 Query DSL을 직접 구성할 수 있습니다.

public List<Product> customSearch(String keyword) {
    Query query = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("description", keyword))
                .filter(QueryBuilders.rangeQuery("price").gte(1000)))
            .build();

    SearchHits<Product> hits = elasticsearchOperations.search(query, Product.class);
    return hits.getSearchHits().stream()
            .map(SearchHit::getContent)
            .collect(Collectors.toList());
}

→ ElasticsearchOperations를 통해 유연한 쿼리 가능


7. 운영환경 적용 전략

항목 전략

Index 설계 사용 목적에 따라 복수 인덱스 사용 (예: product, product_log 등)
매핑 전략 Text vs Keyword 구분 철저히 (정렬, 집계 등)
로그 관리 검색 요청 로그와 처리 시간 측정 필수
스케일 아웃 Node 기반 확장 가능, 별도 클러스터 운영 고려
보안 인증 토큰, HTTPS 설정, 내부망 구성 권장

마무리 요약

항목 요약

주요 구성 @Document 엔티티 + Repository 기반 쿼리
고급 기능 Query DSL, 복합 조건 필터링, 분석기 설정
장점 빠른 텍스트 검색, 복합 조건 처리, 확장성
주의점 매핑 구조 명확히 설계, 운영 시 클러스터 구성 필요
추천 사용처 상품 검색, 게시글 검색, 로그 필터링, 실시간 모니터링

다음 편 예고

Spring Boot 시리즈 37편: Prometheus + Grafana – 모니터링 시스템 구축과 지표 기반 운영 전략

728x90