TransactionFeed 엔티티를 TransactionFeedDocument로 변환하고, 변환된 TransactionFeedDocument를 ELS 인덱스에 저장(색인)함.isDeleted 플래그를 true로 업데이트함.TransactionFeedDocument에 반영하여 ELS 인덱스에도 업데이트.searchFeeds 호출Bool Query를 동적으로 생성.TransactionFeedDocument를 검색.GetFeedSummaryResponseDto로 변환하여 사용자에게 반환.tokenizer: nori_tokenizerfilter:
lowercase: 영문 소문자 변환.nori_part_of_speech: 불필요한 품사(조사, 어미 등)를 제거함. 예를 들어 '아이폰은' -> '아이폰'으로 색인하여, '아이폰'이라는 검색어로 쉽게 찾을 수 있게 함.nori_readingform: 한자 한글 변환.tokenizer: nori_tokenizerfilter:
lowercase: 영문 소문자 변환.nori_readingform: 한자 한글 변환.synonym_graph_filter: 동의어를 확장함. 예를 들어 사용자가 '스크'로 검색하면, 'SKT', 'skt', '에스케이티' 등의 동의어가 모두 포함되어 검색됨.인덱싱 시에는 품사를 제거하여 관련없는 문서가 검색될 확률을 낮추도록 함. 검색 시에는 동의어를 확장하도록 하여, 검색 재현율을 높이도록 함.
String keyword (예: "skt 1기가 팝니다")"skt", "1기가", "팝니다")로 분리.TELECOM_SYNONYM_MAP을 통해 단어가 'skt', '스크' 등 통신사 동의어인지 확인. 만약 해당되면, bool 쿼리의 filter 절에 term 쿼리("telecomCompanyId": 1)를 추가. 텍스트 검색 대상에서는 제외됨.parseDataAmount 메서드를 통해 단어가 '1기가', '500mb' 등 데이터 크기를 나타내는지 파싱. 해당되면, filter 절에 term 쿼리("salesDataAmount": 1000)를 추가. 텍스트 검색 대상에서는 제외됨.filter 컨텍스트에 추가됨.multi_match 쿼리를 통해 title, content, nickname 필드에서 검색됨.// TransactionFeedServiceImpl.java 中 searchFeeds 메서드 일부
// ... 키워드를 공백 기준으로 분리 ...
String[] words = keyword.trim().split("\\\\s+");
for (String word : words) {
String lowerWord = word.toLowerCase();
// 1. 통신사 동의어 확인
if (TELECOM_SYNONYM_MAP.containsKey(lowerWord)) {
Long telecomId = TELECOM_SYNONYM_MAP.get(lowerWord);
// boolQueryBuilder에 telecomCompanyId 필터 추가
continue;
}
// 2. 데이터 크기 확인
Long parsedAmount = parseDataAmount(word);
if (parsedAmount != null) {
// boolQueryBuilder에 salesDataAmount 필터 추가
continue;
}
// 3. 남은 단어는 텍스트 검색용으로 수집
textKeywords.add(word);
}
// 남은 텍스트 키워드가 있으면 multi-match 검색 실행
if (!textKeywords.isEmpty()) {
String searchText = String.join(" ", textKeywords);
boolQueryBuilder.filter(f -> f.multiMatch(mm -> mm
.query(searchText)
.fields("title", "content", "nickname",
"title.prefix", "content.prefix", "nickname.prefix")
));
}