diff --git a/src/main/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImpl.java b/src/main/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImpl.java index 1f0c05dc0..c9c70282b 100644 --- a/src/main/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImpl.java +++ b/src/main/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImpl.java @@ -192,7 +192,7 @@ public Page findSearchDtoByKeywordsUnion(List keywords, L nanaTitle.heading, imageFile.originUrl, imageFile.thumbnailUrl, - countMatchingWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수 + getMaxMatchingCountWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수 nana.createdAt )) .from(nana) @@ -200,36 +200,30 @@ public Page findSearchDtoByKeywordsUnion(List keywords, L .leftJoin(nanaTitle).on(nanaTitle.nana.eq(nana).and(nanaTitle.language.eq(language))) .leftJoin(nanaContent).on(nanaContent.nanaTitle.eq(nanaTitle)) .on(nanaTitle.language.eq(language)) + .groupBy(nana.id, nanaTitle.heading, imageFile.originUrl, imageFile.thumbnailUrl, + nana.createdAt) .fetch(); // key: nana_id, value: nanaContent 중 키워드와 가장 많이 일치한 수 Map nanaMap = new HashMap<>(); for (NanaSearchDto nanaSearchDto : resultDto) { Long nanaId = nanaSearchDto.getId(); - Long matchedCount = keywordMatchMap.get(nanaId); + Long matchedCount = nanaSearchDto.getMatchedCount(); nanaMap.put(nanaId, Math.max(nanaMap.getOrDefault(nanaId, 0L), matchedCount)); } - // nana_id 값과 최대 matchedCount 값을 가진 객체만 관리 - List groupedResultDto = new ArrayList<>(); - for (NanaSearchDto nanaSearchDto : resultDto) { - Long nanaId = nanaSearchDto.getId(); - if (nanaSearchDto.getMatchedCount() == nanaMap.get(nanaId)) { - groupedResultDto.add(nanaSearchDto); - } - } // 해시태그 값을 matchedCount에 더해줌 - for (NanaSearchDto nanaSearchDto : groupedResultDto) { + for (NanaSearchDto nanaSearchDto : resultDto) { Long id = nanaSearchDto.getId(); nanaSearchDto.addMatchedCount(keywordMatchMap.getOrDefault(id, 0L)); } // matchedCount가 0이라면 검색결과에서 제거 - groupedResultDto = groupedResultDto.stream() + resultDto = resultDto.stream() .filter(nanaSearchDto -> nanaSearchDto.getMatchedCount() > 0) .toList(); // 매칭된 키워드 수 내림차순, 생성날짜 내림차순 정렬 - List resultList = new ArrayList<>(groupedResultDto); + List resultList = new ArrayList<>(resultDto); resultList.sort(Comparator .comparing(NanaSearchDto::getMatchedCount, Comparator.nullsLast(Comparator.reverseOrder())) @@ -284,7 +278,7 @@ public Page findSearchDtoByKeywordsIntersect(List keyword nanaTitle.heading, imageFile.originUrl, imageFile.thumbnailUrl, - countMatchingWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수 + getMaxMatchingCountWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수 nana.createdAt )) .from(nana) @@ -292,36 +286,30 @@ public Page findSearchDtoByKeywordsIntersect(List keyword .leftJoin(nanaTitle).on(nanaTitle.nana.eq(nana).and(nanaTitle.language.eq(language))) .leftJoin(nanaContent).on(nanaContent.nanaTitle.eq(nanaTitle)) .on(nanaTitle.language.eq(language)) + .groupBy(nana.id, nanaTitle.heading, imageFile.originUrl, imageFile.thumbnailUrl, + nana.createdAt) .fetch(); // key: nana_id, value: nanaContent 중 키워드와 가장 많이 일치한 수 Map nanaMap = new HashMap<>(); for (NanaSearchDto nanaSearchDto : resultDto) { Long nanaId = nanaSearchDto.getId(); - Long matchedCount = keywordMatchMap.get(nanaId); + Long matchedCount = nanaSearchDto.getMatchedCount(); nanaMap.put(nanaId, Math.max(nanaMap.getOrDefault(nanaId, 0L), matchedCount)); } - // nana_id 값과 최대 matchedCount 값을 가진 객체만 관리 - List groupedResultDto = new ArrayList<>(); - for (NanaSearchDto nanaSearchDto : resultDto) { - Long nanaId = nanaSearchDto.getId(); - if (nanaSearchDto.getMatchedCount() == nanaMap.get(nanaId)) { - groupedResultDto.add(nanaSearchDto); - } - } // 해시태그 값을 matchedCount에 더해줌 - for (NanaSearchDto nanaSearchDto : groupedResultDto) { + for (NanaSearchDto nanaSearchDto : resultDto) { Long id = nanaSearchDto.getId(); nanaSearchDto.addMatchedCount(keywordMatchMap.getOrDefault(id, 0L)); } // matchedCount가 키워드 개수와 다르다면 검색결과에서 제거 - groupedResultDto = groupedResultDto.stream() + resultDto = resultDto.stream() .filter(nanaSearchDto -> nanaSearchDto.getMatchedCount() >= keywords.size()) .toList(); // 생성날짜 내림차순 정렬 - List resultList = new ArrayList<>(groupedResultDto); + List resultList = new ArrayList<>(resultDto); resultList.sort(Comparator .comparing(NanaSearchDto::getCreatedAt, Comparator.nullsLast(Comparator.reverseOrder()))); @@ -403,11 +391,12 @@ private List splitKeyword(String keyword) { * @param keywords 키워드 * @return 키워드를 포함하는 조건 개수 */ - private Expression countMatchingWithKeyword(List keywords) { + private Expression getMaxMatchingCountWithKeyword(List keywords) { return Expressions.asNumber(0L) .add(countMatchingConditionWithKeyword(nanaTitle.heading.toLowerCase().trim(), keywords, 0)) - .add(countMatchingConditionWithKeyword(nanaContent.content, keywords, 0)); + .add(countMatchingConditionWithKeyword(nanaContent.content, keywords, 0)) + .max(); } /** diff --git a/src/test/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImplTest.java b/src/test/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImplTest.java index 06a93ecd1..272188434 100644 --- a/src/test/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImplTest.java +++ b/src/test/java/com/jeju/nanaland/domain/nana/repository/NanaRepositoryImplTest.java @@ -1,24 +1,29 @@ package com.jeju.nanaland.domain.nana.repository; +import static org.assertj.core.api.Assertions.assertThat; + import com.jeju.nanaland.config.TestConfig; import com.jeju.nanaland.domain.common.data.Language; import com.jeju.nanaland.domain.common.entity.ImageFile; import com.jeju.nanaland.domain.common.entity.PostImageFile; import com.jeju.nanaland.domain.nana.dto.NanaResponse.PreviewDto; +import com.jeju.nanaland.domain.nana.dto.NanaSearchDto; import com.jeju.nanaland.domain.nana.entity.Nana; import com.jeju.nanaland.domain.nana.entity.NanaContent; import com.jeju.nanaland.domain.nana.entity.NanaTitle; import jakarta.persistence.EntityManager; import java.util.List; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; @DataJpaTest @Import(TestConfig.class) @@ -201,7 +206,7 @@ void findTop4PreviewDtoOrderByCreatedAt() { Language.KOREAN); // Then - Assertions.assertThat(recentPreviewDtoDto.get(0).getId()) + assertThat(recentPreviewDtoDto.get(0).getId()) .isEqualTo(nana5.getId()); } @@ -218,8 +223,8 @@ void findAllPreviewDtoOrderByCreatedAt() { List result = allNanaThumbnailDto.getContent(); // Then - Assertions.assertThat(result.get(0).getId()).isEqualTo(nana5.getId()); - Assertions.assertThat(result.get(result.size() - 1).getId()).isEqualTo(nana1.getId()); + assertThat(result.get(0).getId()).isEqualTo(nana5.getId()); + assertThat(result.get(result.size() - 1).getId()).isEqualTo(nana1.getId()); } @Test @@ -242,21 +247,26 @@ void searchNanaThumbnailDtoByKeyword() { isSearched = true; } } - Assertions.assertThat(isSearched).isTrue(); + assertThat(isSearched).isTrue(); } -// @Test -// void findNanaThumbnailPostDto() { -// // Given -// setNana(); -// -// // When -// NanaThumbnailPost nanaThumbnailPostDto = nanaRepositoryImpl.findNanaThumbnailPostDto( -// nanaTitle3.getId(), Language.KOREAN); -// System.out.println("nanaTitle3 = " + nanaTitle3.getId()); -// System.out.println("nanaThumbnailPostDto.toString() = " + nanaThumbnailPostDto.toString()); -// -// // Then -// Assertions.assertThat(nanaThumbnailPostDto.getId()).isEqualTo(nanaTitle3.getId()); -// } + @ParameterizedTest + @EnumSource(value = Language.class) + void findSearchDtoByKeywordsUnionTest(Language language) { + // given + setNana(); + Pageable pageable = PageRequest.of(0, 12); + + // when + Page resultDto = nanaRepositoryImpl.findSearchDtoByKeywordsUnion( + List.of("content"), language, pageable); + + // then + List content = resultDto.getContent(); + for (NanaSearchDto nanaSearchDto : content) { + System.out.println("============="); + System.out.println(nanaSearchDto.getId()); + } +// assertThat(resultDto.getTotalElements()).isEqualTo(5L); + } } \ No newline at end of file