반응형

RESTful API에서 검색 기능을 구현하고, 성능을 최적화하는 방법에 대해 학습합니다. 검색은 사용자 경험의 핵심 요소이며, 이를 효율적으로 처리하기 위해 데이터베이스 설계와 쿼리 최적화가 중요합니다.


1. 검색 기능의 기본 개념

검색 기능은 사용자가 원하는 데이터를 쉽게 찾아볼 수 있도록 지원하는 기능입니다.

  • 기본 검색: 단순 키워드 기반 검색
  • 필터 검색: 여러 조건을 결합한 검색
  • 정렬 옵션: 결과를 특정 필드 기준으로 정렬

2. 데이터베이스 설계

1) 검색 가능한 데이터 구조

검색 필드에 인덱스를 추가하여 성능을 향상시킬 수 있습니다.
예: MySQL에서 FULLTEXT INDEX를 사용하거나 Elasticsearch를 통합하여 고급 검색 기능을 구현합니다.

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    description TEXT,
    price DECIMAL(10, 2),
    category VARCHAR(100),
    FULLTEXT (name, description)
);

2) 데이터 정규화와 비정규화

  • 정규화: 중복 데이터를 제거하여 데이터 무결성을 보장
  • 비정규화: 검색 성능을 높이기 위해 일부 중복 데이터를 허용

3. 기본 검색 API 구현

Controller

import org.springframework.web.bind.annotation.*;
import java.util.List;

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

    private final ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

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

Service

import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductService {

    private final ProductRepository productRepository;

    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public List<Product> searchProducts(String keyword) {
        return productRepository.findByNameContainingOrDescriptionContaining(keyword, keyword);
    }
}

Repository

import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;

public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByNameContainingOrDescriptionContaining(String name, String description);
}

4. 고급 검색 기능

필터 및 정렬 옵션 추가

@GetMapping("/search")
public List<Product> searchProducts(
        @RequestParam String keyword,
        @RequestParam(required = false) String category,
        @RequestParam(required = false, defaultValue = "price") String sortBy,
        @RequestParam(required = false, defaultValue = "asc") String order) {

    return productService.searchProducts(keyword, category, sortBy, order);
}

Service 레벨 필터 처리

public List<Product> searchProducts(String keyword, String category, String sortBy, String order) {
    if (category != null && !category.isEmpty()) {
        return productRepository.findByCategoryAndNameContainingOrDescriptionContaining(
                category, keyword, keyword, Sort.by(Sort.Direction.fromString(order), sortBy));
    } else {
        return productRepository.findByNameContainingOrDescriptionContaining(
                keyword, keyword, Sort.by(Sort.Direction.fromString(order), sortBy));
    }
}

5. 성능 최적화

1) 데이터베이스 인덱싱

  • B-Tree 인덱스: 정렬된 검색에 유리
  • FULLTEXT 인덱스: 자연어 기반 검색에 적합

2) 캐싱 사용

자주 요청되는 검색 결과는 캐싱하여 데이터베이스 부하를 줄입니다.
예: Spring Cache와 Redis를 통합하여 구현.

@Cacheable(value = "searchResults", key = "#keyword")
public List<Product> searchProducts(String keyword) {
    return productRepository.findByNameContainingOrDescriptionContaining(keyword, keyword);
}

3) 페이징 처리

검색 결과가 많을 경우 페이징을 적용합니다.

@GetMapping("/search")
public Page<Product> searchProducts(
        @RequestParam String keyword,
        @RequestParam(required = false, defaultValue = "0") int page,
        @RequestParam(required = false, defaultValue = "10") int size) {

    return productService.searchProducts(keyword, PageRequest.of(page, size));
}

6. 외부 도구 통합

Elasticsearch

대규모 데이터에서 고속 검색을 제공하는 도구입니다.
Elasticsearch를 사용하면 복잡한 검색 조건과 높은 성능을 동시에 얻을 수 있습니다.

@Document(indexName = "products")
public class Product {
    @Id
    private String id;
    private String name;
    private String description;
    private double price;
    private String category;
}

7. 테스트

  1. 기본 검색
    /api/products/search?keyword=laptop
    • 상품 이름 또는 설명에 laptop이 포함된 데이터를 반환합니다.
  2. 필터 검색
    /api/products/search?keyword=laptop&category=electronics
    • electronics 카테고리에 속하는 데이터를 필터링합니다.
  3. 정렬 옵션 적용
    /api/products/search?keyword=laptop&sortBy=price&order=desc
    • 가격 기준으로 내림차순 정렬합니다.
반응형

+ Recent posts