Skip to content

Commit

Permalink
Merge branch 'fix/#527-searchExperience' of https://github.com/Travel…
Browse files Browse the repository at this point in the history
…-in-nanaland/Back-end into fix/#527-searchExperience
  • Loading branch information
heeeeeseok committed Dec 16, 2024
2 parents 767b1d3 + 5d9843c commit d50a058
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ PopularPostPreviewDto findRandomPopularPostPreviewDtoByLanguage(Language languag

PopularPostPreviewDto findPostPreviewDtoByLanguageAndId(Language language, Long postId);

Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(List<String> keywords, Language language,
Pageable pageable);
Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(ExperienceType experienceType,
List<String> keywords, Language language, Pageable pageable);

Page<ExperienceSearchDto> findSearchDtoByKeywordsIntersect(List<String> keywords,
Language language, Pageable pageable);
Page<ExperienceSearchDto> findSearchDtoByKeywordsIntersect(ExperienceType experienceType,
List<String> keywords, Language language, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ public ExperienceCompositeDto findCompositeDtoByIdWithPessimisticLock(Long id,
}

@Override
public Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(List<String> keywords,
Language language, Pageable pageable) {
public Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(ExperienceType experienceType,
List<String> keywords, Language language, Pageable pageable) {

// experience_id를 가진 게시물의 해시태그가 검색어 키워드 중 몇개를 포함하는지 계산
List<Tuple> keywordMatchQuery = queryFactory
Expand All @@ -123,7 +123,9 @@ public Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(List<String> keywo
.on(hashtag.post.id.eq(experience.id)
.and(hashtag.language.eq(language)))
.innerJoin(hashtag.keyword, QKeyword.keyword)
.where(QKeyword.keyword.content.toLowerCase().trim().in(keywords))
.where(
experience.experienceType.eq(experienceType),
QKeyword.keyword.content.toLowerCase().trim().in(keywords))
.groupBy(experience.id)
.fetch();

Expand All @@ -146,6 +148,7 @@ public Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(List<String> keywo
.leftJoin(experience.firstImageFile, imageFile)
.leftJoin(experience.experienceTrans, experienceTrans)
.on(experienceTrans.language.eq(language))
.where(experience.experienceType.eq(experienceType))
.fetch();

// 해시태그 값을 matchedCount에 더해줌
Expand Down Expand Up @@ -176,8 +179,9 @@ public Page<ExperienceSearchDto> findSearchDtoByKeywordsUnion(List<String> keywo
}

@Override
public Page<ExperienceSearchDto> findSearchDtoByKeywordsIntersect(List<String> keywords,
Language language, Pageable pageable) {
public Page<ExperienceSearchDto> findSearchDtoByKeywordsIntersect(
ExperienceType experienceType, List<String> keywords, Language language,
Pageable pageable) {

// experience_id를 가진 게시물의 해시태그가 검색어 키워드 중 몇개를 포함하는지 계산
List<Tuple> keywordMatchQuery = queryFactory
Expand All @@ -187,7 +191,9 @@ public Page<ExperienceSearchDto> findSearchDtoByKeywordsIntersect(List<String> k
.on(hashtag.post.id.eq(experience.id)
.and(hashtag.language.eq(language)))
.innerJoin(hashtag.keyword, QKeyword.keyword)
.where(QKeyword.keyword.content.toLowerCase().trim().in(keywords))
.where(
experience.experienceType.eq(experienceType),
QKeyword.keyword.content.toLowerCase().trim().in(keywords))
.groupBy(experience.id)
.fetch();

Expand All @@ -210,6 +216,7 @@ public Page<ExperienceSearchDto> findSearchDtoByKeywordsIntersect(List<String> k
.leftJoin(experience.firstImageFile, imageFile)
.leftJoin(experience.experienceTrans, experienceTrans)
.on(experienceTrans.language.eq(language))
.where(experience.experienceType.eq(experienceType))
.fetch();

// 해시태그 값을 matchedCount에 더해줌
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.jeju.nanaland.global.exception.SuccessCode.SEARCH_SUCCESS;

import com.jeju.nanaland.domain.experience.entity.enums.ExperienceType;
import com.jeju.nanaland.domain.member.dto.MemberResponse.MemberInfoDto;
import com.jeju.nanaland.domain.search.dto.SearchResponse;
import com.jeju.nanaland.domain.search.dto.SearchResponse.AllCategoryDto;
Expand Down Expand Up @@ -95,12 +96,13 @@ public BaseResponse<SearchResponse.ResultDto> searchFestival(
@GetMapping("/experience")
public BaseResponse<SearchResponse.ResultDto> searchExperience(
@AuthMember MemberInfoDto memberInfoDto,
@RequestParam ExperienceType experienceType,
@NotNull String keyword,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "12") int size) {

ResultDto result = searchService.searchExperience(memberInfoDto, keyword, page,
size);
ResultDto result = searchService.searchExperience(memberInfoDto, experienceType, keyword,
page, size);
return BaseResponse.success(SEARCH_SUCCESS, result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ public static class AllCategoryDto {
@Schema(description = "7대자연 조회 결과")
private ResultDto nature;

@Schema(description = "이색체험 조회 결과")
private ResultDto experience;
@Schema(description = "액티비티 조회 결과")
private ResultDto activity;

@Schema(description = "문화예술 조회 결과")
private ResultDto cultureAndArts;

@Schema(description = "전통시장 조회 결과")
private ResultDto market;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.jeju.nanaland.domain.common.data.Language;
import com.jeju.nanaland.domain.common.dto.CompositeDto;
import com.jeju.nanaland.domain.experience.dto.ExperienceSearchDto;
import com.jeju.nanaland.domain.experience.entity.enums.ExperienceType;
import com.jeju.nanaland.domain.experience.repository.ExperienceRepository;
import com.jeju.nanaland.domain.favorite.service.MemberFavoriteService;
import com.jeju.nanaland.domain.festival.dto.FestivalSearchDto;
Expand Down Expand Up @@ -81,8 +82,11 @@ public SearchResponse.AllCategoryDto searchAll(MemberInfoDto memberInfoDto, Stri
() -> searchFestival(memberInfoDto, keyword, page, size));
CompletableFuture<SearchResponse.ResultDto> marketFuture = CompletableFuture.supplyAsync(
() -> searchMarket(memberInfoDto, keyword, page, size));
CompletableFuture<SearchResponse.ResultDto> experienceFuture = CompletableFuture.supplyAsync(
() -> searchExperience(memberInfoDto, keyword, page, size));
CompletableFuture<SearchResponse.ResultDto> activityFuture = CompletableFuture.supplyAsync(
() -> searchExperience(memberInfoDto, ExperienceType.ACTIVITY, keyword, page, size));
CompletableFuture<SearchResponse.ResultDto> cultureAndArtsFuture = CompletableFuture.supplyAsync(
() -> searchExperience(memberInfoDto, ExperienceType.CULTURE_AND_ARTS, keyword, page,
size));
CompletableFuture<SearchResponse.ResultDto> restaurantFuture = CompletableFuture.supplyAsync(
() -> searchRestaurant(memberInfoDto, keyword, page, size));
CompletableFuture<SearchResponse.ResultDto> nanaFuture = CompletableFuture.supplyAsync(
Expand All @@ -93,7 +97,8 @@ public SearchResponse.AllCategoryDto searchAll(MemberInfoDto memberInfoDto, Stri
natureFuture,
festivalFuture,
marketFuture,
experienceFuture,
activityFuture,
cultureAndArtsFuture,
restaurantFuture,
nanaFuture
).join();
Expand All @@ -103,7 +108,8 @@ public SearchResponse.AllCategoryDto searchAll(MemberInfoDto memberInfoDto, Stri
.nature(natureFuture.join())
.festival(festivalFuture.join())
.market(marketFuture.join())
.experience(experienceFuture.join())
.activity(activityFuture.join())
.cultureAndArts(cultureAndArtsFuture.join())
.restaurant(restaurantFuture.join())
.nana(nanaFuture.join())
.build();
Expand Down Expand Up @@ -223,8 +229,8 @@ public SearchResponse.ResultDto searchFestival(MemberInfoDto memberInfoDto, Stri
* @param size 페이지 크기
* @return 이색체험 검색 결과
*/
public SearchResponse.ResultDto searchExperience(MemberInfoDto memberInfoDto, String keyword,
int page, int size) {
public SearchResponse.ResultDto searchExperience(MemberInfoDto memberInfoDto,
ExperienceType experienceType, String keyword, int page, int size) {

Language language = memberInfoDto.getLanguage();
Member member = memberInfoDto.getMember();
Expand All @@ -236,13 +242,13 @@ public SearchResponse.ResultDto searchExperience(MemberInfoDto memberInfoDto, St
Page<ExperienceSearchDto> resultPage;
// 공백으로 구분한 키워드가 4개 이하라면 Union 검색
if (normalizedKeywords.size() <= 4) {
resultPage = experienceRepository.findSearchDtoByKeywordsUnion(normalizedKeywords,
language, pageable);
resultPage = experienceRepository.findSearchDtoByKeywordsUnion(experienceType,
normalizedKeywords, language, pageable);
}
// 4개보다 많다면 Intersect 검색
else {
resultPage = experienceRepository.findSearchDtoByKeywordsIntersect(normalizedKeywords,
language, pageable);
resultPage = experienceRepository.findSearchDtoByKeywordsIntersect(experienceType,
normalizedKeywords, language, pageable);
}

List<Long> favoriteIds = memberFavoriteService.getFavoritePostIdsWithMember(member);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ void getExperienceTypeKeywordSetTest() {

@ParameterizedTest
@EnumSource(value = Language.class)
void findSearchDtoByKeywordsUnionTest(Language language) {
@DisplayName("액티비티 Union 검색")
void findSearchDtoByKeywordsUnionActivityTest(Language language) {
// given
Pageable pageable = PageRequest.of(0, 10);
List<Experience> experiences1 =
Expand All @@ -149,17 +150,39 @@ void findSearchDtoByKeywordsUnionTest(Language language) {

// when
Page<ExperienceSearchDto> resultDto = experienceRepository.findSearchDtoByKeywordsUnion(
List.of("keyword2", "keyword3"), language, pageable);
ExperienceType.ACTIVITY, List.of("keyword2", "keyword3"), language, pageable);

// then
assertThat(resultDto.getTotalElements()).isEqualTo(5);
assertThat(resultDto.getTotalElements()).isEqualTo(2);
assertThat(resultDto.getContent().get(0).getMatchedCount()).isEqualTo(1);
}

@ParameterizedTest
@EnumSource(value = Language.class)
@DisplayName("문화예술 Union 검색")
void findSearchDtoByKeywordsUnionCultureAndArtsTest(Language language) {
// given
Pageable pageable = PageRequest.of(0, 10);
List<Experience> experiences1 =
getActivityList(language, List.of(LAND_LEISURE, WATER_LEISURE), "제주시", 2);
initHashtags(experiences1, List.of("keyword1", "kEyWoRd2"), language);
List<Experience> experiences2 =
getCultureAndArtsList(language, List.of(EXHIBITION, MUSEUM, ART_MUSEUM), "서귀포시", 3);
initHashtags(experiences2, List.of("keyword2", "kEyWoRd3"), language);

// when
Page<ExperienceSearchDto> resultDto = experienceRepository.findSearchDtoByKeywordsUnion(
ExperienceType.CULTURE_AND_ARTS, List.of("keyword2", "keyword3"), language, pageable);

// then
assertThat(resultDto.getTotalElements()).isEqualTo(3);
assertThat(resultDto.getContent().get(0).getMatchedCount()).isEqualTo(2);
assertThat(resultDto.getContent().get(3).getMatchedCount()).isEqualTo(1);
}

@ParameterizedTest
@EnumSource(value = Language.class)
void findSearchDtoByKeywordsIntersectTest(Language language) {
@DisplayName("액티비티 Union 검색")
void findSearchDtoByKeywordsIntersectActivityTest(Language language) {
// given
Pageable pageable = PageRequest.of(0, 10);
List<String> keywords = List.of("keyword1", "keyword2", "keyword3", "keyword4", "keyword5");
Expand All @@ -168,16 +191,38 @@ void findSearchDtoByKeywordsIntersectTest(Language language) {
initHashtags(experiences1, keywords, language);
List<Experience> experiences2 =
getCultureAndArtsList(language, List.of(EXHIBITION, MUSEUM, ART_MUSEUM), "서귀포시", 3);
initHashtags(experiences2, List.of("keyword1", "kEyWoRd2"), language);
initHashtags(experiences2, keywords, language);

// when
Page<ExperienceSearchDto> resultDto = experienceRepository.findSearchDtoByKeywordsIntersect(
keywords, language, pageable);
ExperienceType.ACTIVITY, keywords, language, pageable);

// then
assertThat(resultDto.getTotalElements()).isEqualTo(2);
}

@ParameterizedTest
@EnumSource(value = Language.class)
@DisplayName("문화예술 Union 검색")
void findSearchDtoByKeywordsIntersectCultureAndArtsTest(Language language) {
// given
Pageable pageable = PageRequest.of(0, 10);
List<String> keywords = List.of("keyword1", "keyword2", "keyword3", "keyword4", "keyword5");
List<Experience> experiences1 =
getActivityList(language, List.of(LAND_LEISURE, WATER_LEISURE), "제주시", 2);
initHashtags(experiences1, keywords, language);
List<Experience> experiences2 =
getCultureAndArtsList(language, List.of(EXHIBITION, MUSEUM, ART_MUSEUM), "서귀포시", 3);
initHashtags(experiences2, keywords, language);

// when
Page<ExperienceSearchDto> resultDto = experienceRepository.findSearchDtoByKeywordsIntersect(
ExperienceType.CULTURE_AND_ARTS, keywords, language, pageable);

// then
assertThat(resultDto.getTotalElements()).isEqualTo(3);
}

private List<Experience> getActivityList(Language language,
List<ExperienceTypeKeyword> keywordList, String addressTag, int size) {
List<Experience> experienceList = new ArrayList<>();
Expand Down

0 comments on commit d50a058

Please sign in to comment.