Skip to content

Commit

Permalink
[feat] Influencer 검색기능(Pagination) 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
sanghee0820 committed Nov 14, 2024
1 parent b030d80 commit c85ee52
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
37 changes: 37 additions & 0 deletions src/main/java/team7/inplace/search/application/SearchService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team7.inplace.favoriteInfluencer.persistent.FavoriteInfluencerRepository;
import team7.inplace.influencer.application.dto.InfluencerInfo;
import team7.inplace.influencer.domain.Influencer;
import team7.inplace.likedPlace.persistence.LikedPlaceRepository;
import team7.inplace.search.application.dto.AutoCompletionInfo;
import team7.inplace.search.application.dto.PlaceSearchInfo;
import team7.inplace.search.application.dto.SearchType;
import team7.inplace.search.persistence.InfluencerSearchRepository;
import team7.inplace.search.persistence.PlaceSearchRepository;
import team7.inplace.search.persistence.VideoSearchRepository;
import team7.inplace.search.persistence.dto.SearchResult;
import team7.inplace.security.util.AuthorizationUtil;
import team7.inplace.video.application.dto.VideoInfo;

Expand Down Expand Up @@ -80,6 +85,38 @@ public List<InfluencerInfo> searchInfluencer(String keyword) {
.toList();
}

public Page<InfluencerInfo> searchInfluencer(String keyword, Pageable pageable) {
Page<SearchResult<Influencer>> influencerInfos = influencerSearchRepository.searchEntityByKeywords(keyword,
pageable);
Long userId = AuthorizationUtil.getUserId();

if (userId == null) {
return new PageImpl<>(
influencerInfos.getContent().stream()
.map(influencer -> InfluencerInfo.from(influencer.searchResult(), false))
.toList(),
pageable,
influencerInfos.getTotalElements()
);
}

var likedInfluencerIds = favoriteInfluencerRepository.findLikedInfluencerIdsByUserId(userId);

List<InfluencerInfo> sortedContent = influencerInfos.getContent().stream()
.map(influencerInfo -> {
boolean isLiked = likedInfluencerIds.contains(influencerInfo.searchResult().getId());
return InfluencerInfo.from(influencerInfo.searchResult(), isLiked);
})
.sorted((a, b) -> Boolean.compare(b.likes(), a.likes()))
.toList();

return new PageImpl<>(
sortedContent,
pageable,
influencerInfos.getTotalElements()
);
}

public List<PlaceSearchInfo> searchPlace(String keyword) {
var placeInfos = placeSearchRepository.searchEntityByKeywords(keyword);
Long userId = AuthorizationUtil.getUserId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import team7.inplace.influencer.domain.Influencer;
import team7.inplace.influencer.domain.QInfluencer;
Expand Down Expand Up @@ -40,4 +43,40 @@ public List<SearchResult<Influencer>> searchEntityByKeywords(String keyword) {
tuple.get(1, Double.class)
)).toList();
}

public Page<SearchResult<Influencer>> searchEntityByKeywords(String keyword, Pageable pageable) {
NumberTemplate<Double> matchScore = Expressions.numberTemplate(
Double.class,
"function('match_against', {0}, {1})",
QInfluencer.influencer.name,
keyword
);

// 결과 조회
List<SearchResult<Influencer>> content = queryFactory
.select(
QInfluencer.influencer,
matchScore.as("score")
)
.from(QInfluencer.influencer)
.where(matchScore.gt(0))
.orderBy(matchScore.desc())
.offset(pageable.getOffset()) // 페이지 오프셋
.limit(pageable.getPageSize()) // 페이지 사이즈
.fetch()
.stream()
.map(tuple -> new SearchResult<>(
tuple.get(0, Influencer.class),
tuple.get(1, Double.class)
)).toList();

// 전체 카운트 조회
long total = queryFactory
.select(QInfluencer.influencer.count())
.from(QInfluencer.influencer)
.where(matchScore.gt(0))
.fetchOne();

return new PageImpl<>(content, pageable, total);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import team7.inplace.influencer.application.dto.InfluencerInfo;
import team7.inplace.influencer.presentation.dto.InfluencerResponse;
import team7.inplace.search.application.SearchService;
import team7.inplace.search.application.dto.AutoCompletionInfo;
Expand Down Expand Up @@ -50,11 +54,24 @@ public ResponseEntity<List<InfluencerResponse>> searchInfluencer(@RequestParam S
return new ResponseEntity<>(response, HttpStatus.OK);
}

@Override
@GetMapping("/page/influencer")
public ResponseEntity<Page<InfluencerResponse>> searchInfluencer(
@RequestParam String value,
@PageableDefault(size = 10) Pageable pageable
) {
Page<InfluencerInfo> influencers = searchService.searchInfluencer(value, pageable);

Page<InfluencerResponse> response = influencers.map(InfluencerResponse::from);

return new ResponseEntity<>(response, HttpStatus.OK);
}

@Override
@GetMapping("/place")
public ResponseEntity<List<PlaceSearchInfo>> searchPlace(@RequestParam String value) {
var places = searchService.searchPlace(value);

return new ResponseEntity<>(places, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import team7.inplace.influencer.presentation.dto.InfluencerResponse;
import team7.inplace.search.application.dto.AutoCompletionInfo;
Expand All @@ -28,4 +31,8 @@ public interface SearchControllerApiSpec {
@Operation(summary = "장소를 검색합니다.")
@ApiResponse(responseCode = "200", description = "장소 검색 성공")
ResponseEntity<List<PlaceSearchInfo>> searchPlace(String value);

@Operation(summary = "인플루언서를 페이지로 조회합니다.")
@ApiResponse(responseCode = "200", description = "인플루언서 페이지 조회 성공")
ResponseEntity<Page<InfluencerResponse>> searchInfluencer(String value, @PageableDefault Pageable pageable);
}

0 comments on commit c85ee52

Please sign in to comment.