Skip to content

Commit 0a2618e

Browse files
authored
refactor : ElasticSearch 제거 및 QueryDSL 기반 검색/자동완성 기능 구현 (#198)
* refact : 검색 API ES 대신 임시 코드로 대체 - 우선은 검색어 자동완성 기능을 비활성화하고, 문제 검색 기능은 제목과 설명만 포함되도록 함 - ES 비활성화 테스트를 위한 임시방편이므로 추후 추가적인 작업 필요 * fix : NoSuchBeanDefinitionException 예외 해결 - 스프링이 기본 트랜잭션 매니저를 찾지 못해 JPA를 사용할 때마다 NoSuchBeanDefinitionException 예외가 발생하고 있었음 - 이전에 테스트했을 때는 정상적으로 동작했었는데, 코드를 업데이트하면서 문제가 발생한 것으로 보임 - 현재 프로젝트에는 JPA(MySQL)와 MongoDB 두 가지 데이터 소스가 공존하고 있음 - 이름 없는 @transactional은 무조건 JPA(MySQL)가 처리하도록 명시하기 위해 `JpaTransactionConfig` 클래스를 생성함 * feat : 키워드 검색 기능 구현 - Elastic Search에서 담당하던 키워드 검색 기능을 기존의 문제 목록 조회 API에 덧붙이는 형식으로 구현함 - 기존에는 키워드 검색 기능과 카테고리, 난이도별 필터링 검색 API 분리되어 있었음 * feat : 키워드 자동 완성 기능 구현 - API 경로나 반환 타입 등은 기존과 동일하게 유지 - 문제의 제목, 설명과 카테고리 한글명 등을 대상으로 검색어 자동완성을 수행함 - 설명(description)에 키워드가 있어도, 자동완성 목록에는 '제목(title)'을 보여주도록 함 * refact : 더 이상 사용되지 않는 elastic search 관련 파일들 삭제 및 코드 수정 * refact : soft delete 문제 수정 * refactor : es 관련 파일 삭제 * refactor : 테스트 실패 문제 해결
1 parent fb8282e commit 0a2618e

33 files changed

+220
-1082
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ jobs:
2424
ACTIVEMQ_PASSWORD: ${{ secrets.ACTIVEMQ_PASSWORD }}
2525
ACTIVEMQ_PORT: ${{ secrets.ACTIVEMQ_PORT }}
2626
JUDGE0_URL: ${{ secrets.JUDGE0_URL }}
27-
ELASTICSEARCH_ADDRESS: ${{ secrets.ELASTICSEARCH_ADDRESS }}
28-
ELASTICSEARCH_USERNAME: ${{ secrets.ELASTICSEARCH_USERNAME }}
29-
ELASTICSEARCH_PASSWORD: ${{ secrets.ELASTICSEARCH_PASSWORD }}
30-
ELASTICSEARCH_PORT: ${{ secrets.ELASTICSEARCH_PORT }}
3127
OPEN_API_URL: ${{ secrets.OPEN_API_URL }}
3228
OPEN_API_KEY: ${{ secrets.OPEN_API_KEY }}
3329
CLIENT_ID: ${{ secrets.CLIENT_ID }}

build.gradle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ dependencies {
8181
implementation 'org.springframework.boot:spring-boot-starter-actuator'
8282
runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
8383

84-
// elasticsearch + elasticsearch 쿼리빌더 dsl
85-
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
86-
implementation 'co.elastic.clients:elasticsearch-java:8.18.2'
87-
8884
// activemq
8985
implementation 'org.apache.activemq:activemq-broker:6.1.6'
9086

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ my.ezcode.codetest
140140
| **🖥️ 언어** | Java 17 |
141141
| **🔧 백엔드** | Spring Boot, Spring Data JPA, QueryDSL |
142142
| **🔐 보안** | Spring Security, JWT |
143-
| **💾 데이터베이스** | MySQL, Redis, MongoDB, Elastic search |
143+
| **💾 데이터베이스** | MySQL, Redis, MongoDB |
144144
| **📨 메시지 큐** | ActiveMQ, Redis Stream |
145145
| **🧠 개발 도구 (IDE)** | IntelliJ IDEA |
146146
| **🌐 외부 API** | Gmail SMTP, OpenAI, Judge0 |

src/main/java/org/ezcode/codetest/application/problem/dto/response/ProblemSearchResponse.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/main/java/org/ezcode/codetest/application/problem/service/ProblemSearchService.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.List;
44
import java.util.Map;
5+
import java.util.Set;
56
import java.util.stream.Collectors;
67

78
import org.ezcode.codetest.application.problem.dto.request.CategoryCreateRequest;
@@ -26,7 +27,6 @@
2627
import org.springframework.data.domain.Page;
2728
import org.springframework.data.domain.PageImpl;
2829
import org.springframework.data.domain.Pageable;
29-
import org.springframework.http.ResponseEntity;
3030
import org.springframework.stereotype.Service;
3131
import org.springframework.transaction.annotation.Propagation;
3232
import org.springframework.transaction.annotation.Transactional;
@@ -70,9 +70,16 @@ public void createProblem(ProblemCreateRequest requestDto, MultipartFile image,
7070

7171
}
7272

73+
// 검색 키워드 자동 완성
74+
@Transactional(readOnly = true)
75+
public Set<String> getSearchKeywordSuggestions(String keyword) {
76+
77+
return problemDomainService.getSearchKeywordSuggestions(keyword);
78+
}
79+
7380
// 문제 전체 조회
7481
@Transactional(readOnly = true)
75-
public Page<ProblemResponse> getProblemsList(Pageable pageable, ProblemSearchCondition searchCondition) {
82+
public Page<ProblemResponse> getProblemWithCondition(Pageable pageable, ProblemSearchCondition searchCondition) {
7683

7784
Page<Problem> problemPage = problemDomainService.getProblemBySearchCondition(pageable, searchCondition);
7885
List<Problem> problems = problemPage.getContent();
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.ezcode.codetest.common.config;
2+
3+
import org.ezcode.codetest.presentation.problemmanagement.problem.StringToDifficultyConverter;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.format.FormatterRegistry;
6+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7+
8+
@Configuration
9+
public class WebConfig implements WebMvcConfigurer {
10+
11+
@Override
12+
public void addFormatters(FormatterRegistry registry) {
13+
registry.addConverter(new StringToDifficultyConverter());
14+
}
15+
}
Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
11
package org.ezcode.codetest.domain.problem.model;
22

3+
import org.ezcode.codetest.domain.problem.model.enums.Difficulty;
4+
35
public record ProblemSearchCondition(
4-
String category,
56

6-
String difficulty
7+
String categoryCode,
8+
9+
Difficulty difficulty,
10+
11+
String keyword
712

813
) {
14+
15+
public ProblemSearchCondition {
16+
17+
categoryCode = cleanString(categoryCode);
18+
keyword = cleanString(keyword);
19+
}
20+
21+
private static String cleanString(String input) {
22+
23+
if (input == null || input.isBlank()) {
24+
return null;
25+
}
26+
return input.trim();
27+
}
928
}

0 commit comments

Comments
 (0)