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

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

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

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

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

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

✅ 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
series
실전에서 바로 써먹는 Elasticsearch 입문 (검색 최적화편)
slug
type
series-footer
updatedAt
Dec 6, 2025 05:12 AM
📎
이 글은 실전에서 바로 써먹는 Elasticsearch 입문 (검색 최적화편) 강의의 수업 자료 중 일부입니다.