Files
tasteby/backend-java/src/main/java/com/tasteby/controller/SearchController.java
joungmin 9c2dc9f43a fix(search): #293 검색/벡터 결함 7건 일괄 수정
- SearchController: q 빈값 가드 (HTTP 400) — '%%' LIKE 응답 폭발 차단
- SearchService:
  - keywordSearch: LIKE 와일드카드 escape (%, _, \\)
  - hybrid 모드: semantic 결과에도 attachChannels 호출 (이전: keyword만)
  - ObjectMapper/TypeReference static 재사용 (캐시 hit 경로 GC 압박 완화)
  - 알 수 없는 mode → warn 로그 + keyword fallback (이전: silent)
  - maxDistance를 @Value("${app.search.max-distance:0.57}")로 외부화
- SearchMapper.xml: LIKE 절에 ESCAPE '\\' 추가
- VectorService.searchSimilar: embeddings/first list null/empty 가드 (NPE 방지)
- application.yml: app.search.max-distance (env SEARCH_MAX_DISTANCE) 추가

후속 분리: batch insert + 테스트 (별도 후속 이슈)

Refs: #293
2026-06-15 14:01:59 +09:00

35 lines
1.1 KiB
Java

package com.tasteby.controller;
import com.tasteby.domain.Restaurant;
import com.tasteby.service.SearchService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
@RestController
@RequestMapping("/api/search")
public class SearchController {
private final SearchService searchService;
public SearchController(SearchService searchService) {
this.searchService = searchService;
}
@GetMapping
public List<Restaurant> search(
@RequestParam String q,
@RequestParam(defaultValue = "keyword") String mode,
@RequestParam(defaultValue = "20") int limit) {
// #293 — q 빈값 가드: '%%' LIKE로 응답 폭발 차단
if (q == null || q.isBlank()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "검색어가 필요합니다");
}
if (limit > 100) limit = 100;
if (limit < 1) limit = 1;
return searchService.search(q.trim(), mode, limit);
}
}