Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] 나나스픽 검색 수정 #526

Merged
merged 1 commit into from
Dec 1, 2024
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 @@ -192,44 +192,38 @@ public Page<NanaSearchDto> findSearchDtoByKeywordsUnion(List<String> keywords, L
nanaTitle.heading,
imageFile.originUrl,
imageFile.thumbnailUrl,
countMatchingWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수
getMaxMatchingCountWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수
nana.createdAt
))
.from(nana)
.leftJoin(nana.firstImageFile, imageFile)
.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<Long, Long> 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<NanaSearchDto> 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<NanaSearchDto> resultList = new ArrayList<>(groupedResultDto);
List<NanaSearchDto> resultList = new ArrayList<>(resultDto);
resultList.sort(Comparator
.comparing(NanaSearchDto::getMatchedCount,
Comparator.nullsLast(Comparator.reverseOrder()))
Expand Down Expand Up @@ -284,44 +278,38 @@ public Page<NanaSearchDto> findSearchDtoByKeywordsIntersect(List<String> keyword
nanaTitle.heading,
imageFile.originUrl,
imageFile.thumbnailUrl,
countMatchingWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수
getMaxMatchingCountWithKeyword(keywords), // 제목, 내용, 지역정보와 매칭되는 키워드 개수
nana.createdAt
))
.from(nana)
.leftJoin(nana.firstImageFile, imageFile)
.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<Long, Long> 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<NanaSearchDto> 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<NanaSearchDto> resultList = new ArrayList<>(groupedResultDto);
List<NanaSearchDto> resultList = new ArrayList<>(resultDto);
resultList.sort(Comparator
.comparing(NanaSearchDto::getCreatedAt,
Comparator.nullsLast(Comparator.reverseOrder())));
Expand Down Expand Up @@ -403,11 +391,12 @@ private List<String> splitKeyword(String keyword) {
* @param keywords 키워드
* @return 키워드를 포함하는 조건 개수
*/
private Expression<Long> countMatchingWithKeyword(List<String> keywords) {
private Expression<Long> getMaxMatchingCountWithKeyword(List<String> 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();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -201,7 +206,7 @@ void findTop4PreviewDtoOrderByCreatedAt() {
Language.KOREAN);

// Then
Assertions.assertThat(recentPreviewDtoDto.get(0).getId())
assertThat(recentPreviewDtoDto.get(0).getId())
.isEqualTo(nana5.getId());
}

Expand All @@ -218,8 +223,8 @@ void findAllPreviewDtoOrderByCreatedAt() {
List<PreviewDto> 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
Expand All @@ -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<NanaSearchDto> resultDto = nanaRepositoryImpl.findSearchDtoByKeywordsUnion(
List.of("content"), language, pageable);

// then
List<NanaSearchDto> content = resultDto.getContent();
for (NanaSearchDto nanaSearchDto : content) {
System.out.println("=============");
System.out.println(nanaSearchDto.getId());
}
// assertThat(resultDto.getTotalElements()).isEqualTo(5L);
}
}