Skip to content

Commit

Permalink
Merge pull request #526 from Travel-in-nanaland/fix/#524-search
Browse files Browse the repository at this point in the history
[Fix] 나나스픽 검색 수정
  • Loading branch information
heeeeeseok authored Dec 1, 2024
2 parents 0f97c56 + 4a36560 commit d2b2875
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 47 deletions.
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);
}
}

0 comments on commit d2b2875

Please sign in to comment.