-
Notifications
You must be signed in to change notification settings - Fork 2
검색장소 검색 기능 추가 #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
검색장소 검색 기능 추가 #110
The head ref may contain hidden characters: "20250602_#106_\uAE30\uB2A5\uCD94\uAC00_\uAC80\uC0C9_\uC7A5\uC18C_\uAC80\uC0C9\uAE30\uB2A5_\uCD94\uAC00"
Conversation
|
Warning Rate limit exceeded@daye200 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 47 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
""" Walkthrough검색 기능을 위한 새로운 REST API 및 서비스 계층이 추가되었습니다. 검색 유형, 키워드, 페이지네이션을 지원하며, 장소 정보를 DTO로 반환합니다. 이를 위해 검색 타입 enum, 장소 DTO, 검색 쿼리 메서드, 서비스와 컨트롤러가 각각 신설되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant SearchController
participant SearchService
participant PlaceRepository
Client->>SearchController: GET /api/search/place?type&keyword&page&size
SearchController->>SearchService: searchPlaces(type, keyword, page, size)
SearchService->>PlaceRepository: searchByName/searchByIntro/searchByTag/searchAllFields
PlaceRepository-->>SearchService: Page<Place>
SearchService-->>SearchController: Page<PlaceDto>
SearchController-->>Client: ResponseEntity<Page<PlaceDto>>
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
PR 빌드 검증 결과: ✅ 빌드 성공빌드 검증이 완료되었습니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (3)
src/main/java/jombi/freemates/controller/SearchController.java (1)
5-5: 사용하지 않는 import를 제거하세요.
PlaceService를 import했지만 실제로 사용하지 않고 있습니다.-import jombi.freemates.service.PlaceService;src/main/java/jombi/freemates/service/SearchService.java (1)
54-54: 주석이 실제 클래스명과 일치하지 않습니다.주석에서 "PlaceResponse"라고 했지만 실제로는 "PlaceDto"를 사용하고 있습니다.
- // PlaceResponse는 JSON 응답용 DTO + // PlaceDto는 JSON 응답용 DTOsrc/main/java/jombi/freemates/repository/PlaceRepository.java (1)
34-40: 전체 필드 검색 메서드 성능 최적화를 고려해보세요.OR 조건을 사용한 복합 검색이 구현되었지만, 큰 데이터셋에서는 성능 이슈가 발생할 수 있습니다.
성능 개선을 위해 다음을 고려해보세요:
- 검색 대상 필드에 인덱스 추가
- 풀텍스트 검색 엔진(Elasticsearch 등) 도입 검토
- 필요시 UNION을 사용한 쿼리 분리
현재 구현도 기능적으로는 올바르게 동작할 것입니다.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/main/java/jombi/freemates/controller/SearchController.java(1 hunks)src/main/java/jombi/freemates/model/constant/SearchType.java(1 hunks)src/main/java/jombi/freemates/model/dto/PlaceDto.java(1 hunks)src/main/java/jombi/freemates/repository/PlaceRepository.java(1 hunks)src/main/java/jombi/freemates/service/SearchService.java(1 hunks)
🔇 Additional comments (7)
src/main/java/jombi/freemates/model/constant/SearchType.java (1)
3-12: 검색 타입 enum이 잘 구현되었습니다.enum 구조가 명확하고 defaultType() 메서드를 통해 기본값을 제공하는 것이 좋은 설계입니다. 각 검색 타입별 주석도 명확합니다.
src/main/java/jombi/freemates/model/dto/PlaceDto.java (1)
13-30: DTO 클래스가 잘 구현되었습니다.Lombok 어노테이션을 적절히 사용하여 boilerplate 코드를 줄였고, 필드 타입도 적절합니다. 장소 정보를 담기에 충분한 필드들이 포함되어 있습니다.
src/main/java/jombi/freemates/repository/PlaceRepository.java (5)
7-10: Spring Data 임포트가 올바르게 추가되었습니다.페이지네이션과 쿼리 기능을 위한 필요한 임포트들이 적절히 추가되었습니다.
18-21: 장소명 검색 메서드가 잘 구현되었습니다.대소문자를 구분하지 않는 부분 문자열 검색이 올바르게 구현되었습니다. JPQL 구문과 파라미터 바인딩이 적절합니다.
23-26: 소개 텍스트 검색 메서드가 적절히 구현되었습니다.placeName 검색과 동일한 패턴으로 일관성 있게 구현되었습니다.
28-32: 태그 검색 메서드가 올바르게 구현되었습니다.ElementCollection인 tags를 JOIN하여 검색하고 DISTINCT를 사용해 중복을 제거하는 것이 적절합니다.
18-41: 쿼리 메서드들의 일관성과 구조가 우수합니다.4개의 검색 메서드가 모두 일관된 패턴으로 구현되어 있고, 각각의 용도가 명확합니다. 페이지네이션 지원도 적절히 포함되었습니다.
| @GetMapping("/place") | ||
| public ResponseEntity<Page<PlaceDto>> search( | ||
| @RequestParam(value = "type", required = false) SearchType type, | ||
| @RequestParam("keyword") String keyword, | ||
| @RequestParam(value = "page", defaultValue = "0") int page, | ||
| @RequestParam(value = "size", defaultValue = "10") int size | ||
| ) { | ||
| Page<PlaceDto> result = searchService.searchPlaces(type, keyword, page, size); | ||
| return ResponseEntity.ok(result); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
매개변수 유효성 검증을 추가하세요.
페이지네이션 매개변수와 키워드에 대한 유효성 검증이 필요합니다. page, size가 음수이거나 keyword가 비어있을 수 있습니다.
@GetMapping("/place")
public ResponseEntity<Page<PlaceDto>> search(
@RequestParam(value = "type", required = false) SearchType type,
- @RequestParam("keyword") String keyword,
- @RequestParam(value = "page", defaultValue = "0") int page,
- @RequestParam(value = "size", defaultValue = "10") int size
+ @RequestParam("keyword") @NotBlank String keyword,
+ @RequestParam(value = "page", defaultValue = "0") @Min(0) int page,
+ @RequestParam(value = "size", defaultValue = "10") @Min(1) @Max(100) int size
) {추가로 import에 validation 어노테이션들을 포함해야 합니다:
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.NotBlank;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @GetMapping("/place") | |
| public ResponseEntity<Page<PlaceDto>> search( | |
| @RequestParam(value = "type", required = false) SearchType type, | |
| @RequestParam("keyword") String keyword, | |
| @RequestParam(value = "page", defaultValue = "0") int page, | |
| @RequestParam(value = "size", defaultValue = "10") int size | |
| ) { | |
| Page<PlaceDto> result = searchService.searchPlaces(type, keyword, page, size); | |
| return ResponseEntity.ok(result); | |
| } | |
| // add these imports | |
| import javax.validation.constraints.Min; | |
| import javax.validation.constraints.Max; | |
| import javax.validation.constraints.NotBlank; | |
| @GetMapping("/place") | |
| public ResponseEntity<Page<PlaceDto>> search( | |
| @RequestParam(value = "type", required = false) SearchType type, | |
| @RequestParam("keyword") @NotBlank String keyword, | |
| @RequestParam(value = "page", defaultValue = "0") @Min(0) int page, | |
| @RequestParam(value = "size", defaultValue = "10") @Min(1) @Max(100) int size | |
| ) { | |
| Page<PlaceDto> result = searchService.searchPlaces(type, keyword, page, size); | |
| return ResponseEntity.ok(result); | |
| } |
🤖 Prompt for AI Agents
In src/main/java/jombi/freemates/controller/SearchController.java around lines
21 to 30, add validation for the request parameters to ensure 'page' and 'size'
are non-negative and 'keyword' is not empty. Use validation annotations like
@Min(0) for 'page' and 'size', and @NotBlank for 'keyword'. Also, import the
necessary validation annotations from javax.validation.constraints. This will
prevent invalid input and improve robustness.
| Page<Place> placePage; | ||
| switch (searchType) { | ||
| case NAME: | ||
| placePage = placeRepository.searchByName(keyword, pageable); | ||
| break; | ||
| case INTRO: | ||
| placePage = placeRepository.searchByIntro(keyword, pageable); | ||
| break; | ||
| case TAG: | ||
| placePage = placeRepository.searchByTag(keyword, pageable); | ||
| break; | ||
| case ALL: | ||
| default: | ||
| placePage = placeRepository.searchAllFields(keyword, pageable); | ||
| break; | ||
| } | ||
|
|
||
| return placePage.map(this::toDto); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Repository 메서드 존재 여부를 확인하세요.
서비스에서 호출하는 repository 메서드들(searchByName, searchByIntro, searchByTag, searchAllFields)이 실제로 PlaceRepository에 구현되어 있는지 확인이 필요합니다.
🏁 Script executed:
#!/bin/bash
# Repository 메서드들이 구현되어 있는지 확인
ast-grep --pattern $'interface PlaceRepository {
$$$
searchByName($_, $_) {
$$$
}
$$$
}'
ast-grep --pattern $'searchByIntro'
ast-grep --pattern $'searchByTag'
ast-grep --pattern $'searchAllFields'Length of output: 1037
PlaceRepository에 searchByName 메서드 누락
서비스에서 호출하는 searchByName 메서드가 아래 리포지토리 인터페이스에 정의되어 있지 않습니다. 구현을 추가해주세요:
• 파일: src/main/java/jombi/freemates/repository/PlaceRepository.java
// 예시: 이름 검색 메서드 추가
Page<Place> searchByName(@Param("keyword") String keyword, Pageable pageable);🤖 Prompt for AI Agents
In src/main/java/jombi/freemates/repository/PlaceRepository.java, add the
missing method declarations for searchByName, searchByIntro, searchByTag, and
searchAllFields to match those called in SearchService.java lines 33 to 51.
Define each method to accept a String keyword and Pageable pageable as
parameters and return a Page<Place>. Annotate parameters with @Param("keyword")
as needed. This will ensure the repository interface supports all search methods
used by the service.
| public Page<PlaceDto> searchPlaces( | ||
| SearchType searchType, | ||
| String keyword, | ||
| int page, | ||
| int size | ||
| ) { | ||
| if (searchType == null) { | ||
| searchType = SearchType.defaultType(); | ||
| } | ||
| Pageable pageable = PageRequest.of(page, size, Sort.by("placeName").ascending()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
키워드 매개변수에 대한 유효성 검증을 추가하세요.
키워드가 null이거나 빈 문자열일 경우에 대한 처리가 필요합니다. 또한 page, size 매개변수도 음수값일 수 있습니다.
public Page<PlaceDto> searchPlaces(
SearchType searchType,
String keyword,
int page,
int size
) {
+ if (keyword == null || keyword.trim().isEmpty()) {
+ throw new IllegalArgumentException("검색 키워드는 필수입니다.");
+ }
+ if (page < 0 || size <= 0) {
+ throw new IllegalArgumentException("잘못된 페이지네이션 매개변수입니다.");
+ }
+
if (searchType == null) {
searchType = SearchType.defaultType();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public Page<PlaceDto> searchPlaces( | |
| SearchType searchType, | |
| String keyword, | |
| int page, | |
| int size | |
| ) { | |
| if (searchType == null) { | |
| searchType = SearchType.defaultType(); | |
| } | |
| Pageable pageable = PageRequest.of(page, size, Sort.by("placeName").ascending()); | |
| public Page<PlaceDto> searchPlaces( | |
| SearchType searchType, | |
| String keyword, | |
| int page, | |
| int size | |
| ) { | |
| // Validate keyword | |
| if (keyword == null || keyword.trim().isEmpty()) { | |
| throw new IllegalArgumentException("검색 키워드는 필수입니다."); | |
| } | |
| // Validate pagination parameters | |
| if (page < 0 || size <= 0) { | |
| throw new IllegalArgumentException("잘못된 페이지네이션 매개변수입니다."); | |
| } | |
| if (searchType == null) { | |
| searchType = SearchType.defaultType(); | |
| } | |
| Pageable pageable = PageRequest.of(page, size, Sort.by("placeName").ascending()); | |
| // ... |
🤖 Prompt for AI Agents
In src/main/java/jombi/freemates/service/SearchService.java around lines 22 to
31, add validation for the keyword parameter to check if it is null or an empty
string and handle those cases appropriately. Also validate that the page and
size parameters are not negative, and handle invalid values by either setting
defaults or throwing an exception. This ensures the method behaves correctly
with invalid input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/main/java/jombi/freemates/repository/PlaceRepository.java (2)
21-42: 검색 성능 최적화를 위한 데이터베이스 인덱스 고려가 필요합니다.검색 쿼리들이 placeName, introText, tags 필드에서 LIKE 연산을 수행하므로, 성능 향상을 위해 해당 필드들에 인덱스 생성을 고려해보세요. 특히 전체 검색(searchAllFields)의 경우 복합 쿼리이므로 성능 테스트를 권장합니다.
47-47: 좌표 검색 메서드의 데이터 타입 개선을 고려해보세요.x, y 좌표를 String으로 받고 있는데, 좌표 데이터의 특성상 Double이나 BigDecimal 타입이 더 적절할 수 있습니다. 또한 좌표 범위 검색이나 거리 기반 검색도 향후 필요할 수 있습니다.
좌표 타입을 개선하려면 다음과 같이 변경할 수 있습니다:
-Optional<Place> findByXAndY(String x, String y); +Optional<Place> findByXAndY(Double x, Double y);
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/java/jombi/freemates/repository/PlaceRepository.java(1 hunks)src/main/java/jombi/freemates/service/SearchService.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/jombi/freemates/service/SearchService.java
🔇 Additional comments (6)
src/main/java/jombi/freemates/repository/PlaceRepository.java (6)
12-12: 올바른 @param 임포트가 적용되었습니다.이전 리뷰에서 지적된 잘못된 lettuce core @param 임포트 문제가 올바르게 수정되어 Spring Data의 @param 어노테이션을 사용하고 있습니다.
21-23: 장소명 검색 메서드가 잘 구현되었습니다.JPQL 쿼리가 올바르게 작성되었으며, 대소문자 구분 없는 검색과 매개변수 바인딩이 적절히 적용되었습니다.
26-28: 소개글 검색 메서드가 잘 구현되었습니다.searchByName과 일관된 패턴으로 구현되어 있어 코드의 일관성이 좋습니다.
31-34: 태그 검색 메서드에서 DISTINCT 사용이 적절합니다.ElementCollection인 tags를 검색할 때 DISTINCT를 사용하여 중복 결과를 방지한 것이 올바른 접근입니다.
37-42: 전체 필드 검색에서 LEFT JOIN 사용이 적절합니다.태그가 없는 장소도 검색 결과에 포함시키기 위해 LEFT JOIN을 사용한 것이 올바른 설계입니다. OR 조건과 DISTINCT 사용도 적절합니다.
45-45: 카테고리별 검색 메서드가 간결하게 잘 구현되었습니다.Spring Data JPA의 메서드 명명 규칙을 올바르게 사용하여 간단하고 명확한 구현입니다.
PR 빌드 검증 결과: ✅ 빌드 성공빌드 검증이 완료되었습니다. |
#106
Summary by CodeRabbit