Skip to content

Conversation

@ayoung-dev
Copy link
Collaborator

resolved :

📌 과제 설명

  • 커뮤니티 게시글/봉사활동 모집글 검색 기능 분리
  • 검색 쿼리 리팩토링

👩‍💻 요구 사항과 구현 내용

  • 검색 기능이 포함된 community/recruitboard 기능 search 디렉토리로 이동

  • elastic search 서버 연결 O -> elastic search 검색 / 서버 연결 X -> rdb 검색

  • communityBoardResponseDto 필드에 맞게 CommunityDocument 필드 추가

  • recruitBoardDetailResponseDto, recruitBoardWithCenterResponseDto 필드에 맞게 RecruitBoardDocument 필드 추가

  • findAll() 쿼리 -> findAllByDeletedFalse() 로 변경 (elastic search index 저장 시 deleted = true인 필드 제외)

  • center id로 기관명 조회하는 쿼리 추가 (elastic search index 저장 시 사용)

  • 기존) @query 어노테이션으로 elastic search 검색 -> 동적 쿼리로 검색

  • 기존) elastic search index에서 반환값으로 id를 list로 받아와 rdb에서 재검색 -> responseDto 필드에 맞게 반환값 변경

  • 위치 검색 elastic search의 geo_point(지리 공간 분석) 쿼리로 리팩토링

  • 유사어(오타) 검색 허용 쿼리 추가

  • 검색에 가중치 쿼리 추가 (현재 제목, 본문, 닉네임(기관명) 순서대로 가중치)

✅ PR 포인트 & 궁금한 점

  • 현재 controller에서 elastic search 연결 상태 확인하고 각각 rdb 검색, elastic 검색 service랑 연결하는 형식으로 되어 있습니다.
    elastic 검색은 모두 search 디렉토리에, rdb 검색은 controller는 search에 service단 밑으로는 각 communityboard, recruitboard 디렉토리에 있습니다.
    최대한 범수님의 코드를 건드리지 않고, elastic search 검색과 구분하려는 목적이었는데 이렇게 해도 괜찮을지 의견 물어보고 싶어요.

  • recruit board의 경우 responseDTO에 담기는 정보가 많아 고민을 했는데 모든 정보를 elastic search index에 저장하고 결과 바로 반환 vs. elastic search에는 최소한의 정보만 담고 나머지는 rdb에서 한 번 더 검색 중 고민을 해봤는데
    모두 저장할 경우 빠른 시간, 대신 비용 많이 듬 / 후자는 비용은 줄어들지만 한 번 더 검색해야해서 시간이 오래 걸림.
    어차피 local에서만 elastic search 사용하기 때문에 responseDTO에 담기는 정보들 모두 elastic search index에 저장하였습니다.

  • 기존 @query 어노테이션 -> 동적 쿼리 작성 / query 작성 후 nativeQuery로 한 번 더 감싸서 쿼리 날리는 형식으로 되어있습니다!

  • 코드가 너무 쌓여서 새로 바뀐 user로의 리팩토링은 브런치 새로 파서 진행하겠습니다

@ayoung-dev ayoung-dev self-assigned this Jan 27, 2025
@ayoung-dev ayoung-dev linked an issue Jan 27, 2025 that may be closed by this pull request
2 tasks
github-actions[bot]

This comment was marked as resolved.

@github-actions github-actions bot changed the title [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 [BUILD FAIL] [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 Jan 27, 2025
@github-actions github-actions bot closed this Jan 27, 2025
@ayoung-dev ayoung-dev reopened this Jan 27, 2025
github-actions[bot]

This comment was marked as resolved.

@github-actions github-actions bot changed the title [BUILD FAIL] [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 [BUILD FAIL] [BUILD FAIL] [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 Jan 27, 2025
@github-actions github-actions bot closed this Jan 27, 2025
@ayoung-dev ayoung-dev reopened this Jan 27, 2025
@ayoung-dev ayoung-dev changed the title [BUILD FAIL] [BUILD FAIL] [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 Jan 27, 2025
@ayoung-dev ayoung-dev changed the title [Refactor] 검색 디렉토리 분리 및 쿼리 리팩토링 [REFACTOR] 검색 디렉토리 분리 및 쿼리 리팩토링 Jan 27, 2025
Copy link
Collaborator

@m-a-king m-a-king left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

낯선 코드가 많이 보이네요. 고생하셨습니다 ㅠㅠ

파일 체인지와 커밋을 전전하며 리뷰를 작성하느라 올바르지 않은 피드백이 있을 수 있는데 확인 부탁드리겠습니다!

recruit board의 경우 responseDTO에 담기는 정보가 많아 고민을 했는데 모든 정보를 elastic search index에 저장하고 결과 바로 반환 vs. elastic search에는 최소한의 정보만 담고 나머지는 rdb에서 한 번 더 검색 중 고민을 해봤는데
모두 저장할 경우 빠른 시간, 대신 비용 많이 듬 / 후자는 비용은 줄어들지만 한 번 더 검색해야해서 시간이 오래 걸림.
어차피 local에서만 elastic search 사용하기 때문에 responseDTO에 담기는 정보들 모두 elastic search index에 저장하였습니다.

기존 @query 어노테이션 -> 동적 쿼리 작성 / query 작성 후 nativeQuery로 한 번 더 감싸서 쿼리 날리는 형식으로 되어있습니다!

이 부분은 제가 엘라스틱 서치를 학습하지 않아서 이해가 잘 안되는데, 조금 더 자세히 설명을 들을 수 있을까요?

Comment on lines 30 to 50
@GetMapping("/community-boards/search")
@Operation(summary = "커뮤니티 게시글 키워드 검색", description = "키워드를 포함한 커뮤니티 게시글 목록을 조회합니다.")
public ApiResponse<Page<CommunityBoardResponseDto>> getCommunityBoardsBySearch(
@RequestParam String keyword,
Pageable pageable
) {
if (elasticsearchHealthChecker.isElasticsearchRunning()) {
return ApiResponse.ok(
200,
communityBoardDocumentUseCase.get().getCommunityBoardBySearch(keyword, pageable.getPageNumber()),
"커뮤니티 게시글 검색 리스트 조회 성공"
);
} else {
return ApiResponse.ok(
200,
communityBoardQueryUseCase.getCommunityBoards(keyword, pageable.getPageNumber()),
"커뮤니티 게시글 검색 리스트 조회 성공"
);
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config를 활용해서 전략패턴으로 구현체를 결정시키는 방법은 어떨까요?

혹시 런타임에 동적으로 health 상태가 변경될 search service에 대응하려면, 컨트롤러와 서비스 사이에 하나의 계층을 더 구분하거나, 현 상태로도 괜찮을 것 같습니다!

현 상태로 이어가려면 early return 구조이므로 else가 없어도 될 것 같습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전략 패턴을 사용해볼까 했는데 시간이 오래 걸릴 것 같아 else 없애는 방향으로 수정하였습니다!


import java.util.List;

@ConditionalOnProperty(name = "elastic.search.enabled", havingValue = "true")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엘라스틱 서치 활성화 확인을 위한 어노테이션을 커스텀 해보시는 건 어떤지 제안드려요~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다! 반영했습니당

Copy link
Collaborator

@7zrv 7zrv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼하게 작성하신게 느껴집니다 고생하셨습니다!

Copy link
Collaborator

@leebs0521 leebs0521 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다.

@ayoung-dev ayoung-dev force-pushed the refactor/249-separate-search branch from 9cb0dbc to db60898 Compare February 4, 2025 14:51
@ayoung-dev ayoung-dev changed the title [REFACTOR] 검색 디렉토리 분리 및 쿼리 리팩토링 [REFACTOR] 검색 디렉토리 분리 및 쿼리 리팩토링 Feb 4, 2025
- elastic search enabled = true -> elastic search 검색
- elastic search enabled = false -> rdb 검색
- elastic search healthcheck를 통한 서버 연결 확인 기능 추가
- elastic search enabled = true -> test 실행 (local에서 테스트 시 사용 예정)
- elastic search enabled = false -> test ignore
- elastic search 서버 연결 여부에 따른 분기 추가
- writerNickname, createdAt 필드 추가
- elastic search 검색 조건에 writerNickname 및 가중치 추가
- ResponseDto에 fromDocument 추가
- 기존) elastic search에서 검색 결과 글 id 반환 -> id로 rdb에서 검색 후 communityBoardView 반환
  수정) elastic search 검색 결과인 communityDocument 전체 반환
- elasticsearch 저장을 위한 전체 게시글 조회 메서드 변경
- RecruitBoardWithCenterResponseDto, RecruitBoardDetailResponseDto에 포함되는 필드 모두 추가
- RecruitBoardWithCenterResponseDto, RecruitBoardDetailResponseDto에 fromDocument 추가
- elasticsearch index 저장을 위한 전체 데이터 조회 시 deleted 조건 추가
- 기존) elastic search에서 검색 결과 글 id 반환 -> id로 rdb에서 검색 후 반환
  수정) elastic search 검색 결과인 recruitBoardDocument 전체 반환
- 근처 모집글 검색의 경우 elastic search의 geo_point로 매핑하여 검색하도록 리팩토링
- 유사어 검색 쿼리 추가
- 특정 기관 모집글 조회 RecruitBoardQueryApiController로 이동 (추후 개발 후 다시 이동)
- findDynamicField -> findDynamicFieldByCenterId 네이밍 수정
- recruitboard 조회 쿼리문 형식 수정
- elastic search 활성화 확인 어노테이션 생성 및 적용
- 검색 컨트롤러 else 제거
- elastic search 저장 scheduler 로직 순서 수정 (활성화 체크 우선)
-
- 불필요한 import 제거
- null 처리 추가
@ayoung-dev ayoung-dev force-pushed the refactor/249-separate-search branch from c74f70b to df8c95e Compare February 5, 2025 04:09
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 5, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
76.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@7zrv 7zrv merged commit 4bcb963 into main Feb 5, 2025
2 of 3 checks passed
@7zrv 7zrv deleted the refactor/249-separate-search branch February 5, 2025 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] 검색 도메인 분리 및 Qualifier 적용

5 participants