JSCODE Logo
블로그후기멘토진
회사명 : JSCODE대표 : 박재성사업자 등록번호 : 244-22-01557통신판매업 : 제 2023-인천미추홀-0381 호
학원 명칭 : 제이에스코드(JSCODE)원격학원학원설립ㆍ운영 등록번호 : 제6063호

서울특별시 구로구 경인로 20가길 11(오류동, 아델리아)

Copyright ⓒ 2025 JSCODE - 최상위 현업 개발자들의 프로그래밍 교육 All rights reserved.

이용약관개인정보처리방침
← 블로그 목록으로 돌아가기

[실습] Spring Boot에서 Elasticsearch 활용해 검색 API 만들기

JSCODE 박재성
JSCODE 박재성
1970. 01. 01.
author
JSCODE 박재성
category
Elasticsearch
createdAt
Dec 6, 2025 04:21 AM
isPublic
series
실전에서 바로 써먹는 Elasticsearch 입문 (검색 최적화편)
slug
build-autocomplete-api-build-search-api
type
post
updatedAt

✅ Spring Boot에 검색 API 만들기

  1. Controller에 API 추가하기
    1. ProductController
      @RestController @RequestMapping("products") public class ProductController { ... @GetMapping("/search") public ResponseEntity<List<ProductDocument>> searchProducts( @RequestParam String query, @RequestParam(required = false) String category, @RequestParam(defaultValue = "0") double minPrice, @RequestParam(defaultValue = "1000000000") double maxPrice, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "5") int size ) { List<ProductDocument> products = productService.searchProducts(query, category, minPrice, maxPrice, page, size); return ResponseEntity.ok(products); } ... }
       
  1. Service에 메서드 추가하기
    1. ProductService
      @Service public class ProductService { ... public List<ProductDocument> searchProducts( String query, String category, double minPrice, double maxPrice, int page, int size ) { // multi_match 쿼리 Query multiMatchQuery = MultiMatchQuery.of(m -> m .query(query) .fields("name^3", "description^1", "category^2") .fuzziness("AUTO") )._toQuery(); // term filter 쿼리 : 카테고리가 정확히 일치하는 것만 필터링 List<Query> filters = new ArrayList<>(); if (category != null && !category.isEmpty()) { Query categoryFilter = TermQuery.of(t -> t .field("category.raw") .value(category) )._toQuery(); filters.add(categoryFilter); } // range filter: 가격 범위 필터 Query priceRangeFilter = NumberRangeQuery.of(r -> r .field("price") .gte(minPrice) .lte(maxPrice) )._toRangeQuery()._toQuery(); filters.add(priceRangeFilter); // should: rating > 4.0 Query ratingShould = NumberRangeQuery.of(r -> r .field("rating") .gt(4.0) )._toRangeQuery()._toQuery(); // bool query 조합 Query boolQuery = BoolQuery.of(b -> b .must(multiMatchQuery) .filter(filters) .should(ratingShould) )._toQuery(); // Highlight Query 생성 HighlightParameters highlightParameters = HighlightParameters.builder() .withPreTags("<b>") .withPostTags("</b>") .build(); Highlight highlight = new Highlight(highlightParameters, List.of(new HighlightField("name"))); HighlightQuery highlightQuery = new HighlightQuery(highlight, ProductDocument.class); // NativeQuery 생성 NativeQuery nativeQuery = NativeQuery.builder() .withQuery(boolQuery) .withHighlightQuery(highlightQuery) .withPageable(PageRequest.of(page - 1, size)) .build(); // 쿼리 실행 SearchHits<ProductDocument> searchHits = this.elasticsearchOperations.search(nativeQuery, ProductDocument.class); return searchHits.getSearchHits().stream() .map(hit -> { ProductDocument productDocument = hit.getContent(); String highlightedName = hit.getHighlightField("name").get(0); productDocument.setName(highlightedName); return productDocument; }) .toList(); } ... }
       
  1. 깔끔한 테스트를 위해 기존 데이터 삭제하기
    1. 기존 MySQL 테이블 삭제하기
      1. notion image
         
    2. Kibana에서 Elasticsearch 인덱스 삭제하기
      1. DELETE /propducts
       
  1. Postman으로 테스트를 위한 더미 데이터 집어넣기
    1. { "name": "삼성 노트북 13인치", "description": "최신형 삼성 노트북입니다.", "price": 1200000, "rating": 4.6, "category": "전자제품" } { "name": "삼성 노트북 최신형 15인치", "description": "2025년 최신 15인치 노트북입니다.", "price": 2200000, "rating": 4.8, "category": "전자제품" } { "name": "삼성 스마트폰 A17", "description": "최신형 스마트폰, 휴대전화", "price": 1500000, "rating": 4.5, "category": "휴대폰" }
      notion image
 
  1. 테스트해보기
    1. 요구사항의 모든 내용을 다 테스트해보진 않고 몇 가지만 간단하게 테스트해보자.
    2. 삼성으로 검색해보기
      1. http://localhost:8080/products/search?query=삼성
        • 키워드에 맞게 잘 검색이 된다.
         
    3. 카테고리 필터링 추가해보기
      1. http://localhost:8080/products/search?category=전자제품&query=삼성
        • 카테고리에 맞는 데이터만 조회가 된다.
         
    4. 가격 범위 필터링 추가해보기
      1. http://localhost:8080/products/search?category=전자제품&minPrice=0&maxPrice=1500000&query=삼성
        • 가격 범위에 해당하는 데이터만 조회가 된다.
         
    5. samsung으로 검색해보기
      1. http://localhost:8080/products/search?category=전자제품&minPrice=0&maxPrice=1500000&query=samsung
        • 동의어로도 잘 검색이 된다.
       
      참고) 만약 테스트 코드를 작성할 수 있는 역량을 갖고 있다면, 테스트 코드를 작성해서 더 간편하고 꼼꼼하게 테스트할 수 있을 것이다.
 
 
👨🏻‍🏫
지금까지 구현하고자 한 자동 완성 기능과 검색 기능을 다 구현했다. 다음 강의에서는 로컬 환경에서 띄운 Elasitcsearch를 활용하는 방법이 아닌, 클라우드에서 띄우는 Elasticsearch를 활용하는 방법을 배워볼 것이다.
author
JSCODE 박재성
category
Elasticsearch
createdAt
Dec 6, 2025 03:54 AM
isPublic
series
실전에서 바로 써먹는 Elasticsearch 입문 (검색 최적화편)
slug
type
series-footer
updatedAt
📎
이 글은 실전에서 바로 써먹는 Elasticsearch 입문 (검색 최적화편) 강의의 수업 자료 중 일부입니다.