Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ public class SearchController {

private final SearchService searchService;

@Operation(summary = "테스트용 : 1단계 검색 - BM25")
@GetMapping("/bm25")
public BaseResponse<List<SearchResult>> searchBm25(
@RequestParam @Parameter(description = "검색어", required = true) String query
) {
List<SearchResult> results = searchService.searchOnlyBm25(query);
return BaseResponse.of(SuccessCode.OK, results).getBody();
}

@Operation(summary = "테스트용 : 1단계 검색 - semantic")
@GetMapping("/semantic")
public BaseResponse<List<SearchResult>> searchSemantic(
@RequestParam @Parameter(description = "검색어", required = true) String query
) {
List<SearchResult> results = searchService.searchOnlySemantic(query);
return BaseResponse.of(SuccessCode.OK, results).getBody();
}


@Operation(summary = "1단계 검색(BM25 + 시맨틱)", description = "검색어를 기반으로 BM25 + k-NN 하이브리드 검색을 수행하고 합산하여 상위 결과를 반환합니다. (개인화 미적용)")
@GetMapping("/general")
public BaseResponse<List<SearchResult>> searchGeneral(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ public class GeneralSearchProperties {
private Integer searchSize = 20;

// BM25 가중치
private Float exactBoost = 2.0f;
private Float titleBoost = 3.0f;
private Float summaryBoost = 1.0f;
private Float chunkBoost = 0.5f;
private Float summaryBoost = 1.5f;
private Float fuzzyBoost = 1.0f;
private Float chunkBoost = 1.0f;

// --- [Vector & KNN 설정] ---

private Integer knnK = 60;
private Integer knnNumCandidates = 100;
private Integer knnK = 40;
private Integer knnNumCandidates = 50;
private Float vectorTitleBoost = 3.0f;
private Float vectorSummaryBoost = 1.5f;
private Float vectorContentChunkBoost = 0.8f;
Expand All @@ -37,8 +39,8 @@ public class GeneralSearchProperties {

private double hybridScoreWeight = 50.0;
private double personalScoreWeight = 1.0;
private int RRF_K = 60;
private int RRF_WINDOW_SIZE = 60;
private int RRF_K = 40;
private int RRF_WINDOW_SIZE = 40;

// --- [rerank 가중치 설정] ---
private double rerankDocumentTitleWeight = 0.6;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public class SearchConstants {
static final String SUMMARY_FIELD_FORMAT = "summary^%.1f";
static final String CONTENT_CHUNKS_PATH = "contentChunks";
static final String CHUNK_TEXT_FIELD = "contentChunks.chunkText";
static final String MINIMUM_SHOULD_MATCH = "0";
static final String MINIMUM_SHOULD_MATCH = "1";
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,11 @@

public interface SearchService {

/**
* 1단계 일반 검색 (Retrieval)
* - 목적: 검색 품질 평가(Recall) 및 비로그인 사용자 검색
* - 동작: RRF(BM25 + k-NN) 하이브리드 검색만 수행하여 상위 K개 결과를 반환합니다.
* - 개인화(Re-ranking) 로직이 적용되지 않은 순수 연관도 순입니다.
*/
List<SearchResult> searchOnlyBm25(String query);

List<SearchResult> searchOnlySemantic(String query);

List<SearchResult> searchGeneral(String query);

/**
* 2단계 개인화 검색 (Re-ranking)
* - 목적: 실제 서비스 메인 검색 (로그인 사용자용)
* - 동작:
* 1. 1단계 검색으로 후보군(Top 100) 확보
* 2. 사용자의 프로필 벡터와 문서 간 유사도 계산 (Cosine Similarity)
* 3. 1단계 점수와 2단계 점수를 가중합하여 재정렬
*/
List<SearchResult> searchPersonalized(String query, Long userId);
}
Loading
Loading