Skip to content

Commit

Permalink
[Merge] 2024-06-07 버전 적용 (#218)
Browse files Browse the repository at this point in the history
* [Feat] 관심사 기반 추천 스케쥴링 코드 작성 (#217)

* [Feat] 관심사 기반 추천 스케쥴링 코드 작성

* [Refactor] 독서경험 BaseTimeEntity 상속하지 않도록 수정

* [Refactor] 관심사 id 가져오는 코드 오류 수정

* [Refactor] 서브모듈 업데이트 06/07

---------

Signed-off-by: 이성훈 <[email protected]>
Signed-off-by: simjaeyoun <[email protected]>
Co-authored-by: simjaeyoun <[email protected]>
  • Loading branch information
seonghooni and Simy2 authored Jun 7, 2024
1 parent f32f6d9 commit 39ef1a0
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,9 @@ public class InterestRecommend {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "book_id")
private Book book;

public InterestRecommend(Book b) {
this.middleCategory = b.getMiddleCategory();
this.book = b;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import kr.KWGraduate.BookPharmacy.domain.book.dto.response.BookSearchResponseDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand Down Expand Up @@ -76,4 +77,10 @@ public interface BookRepository extends JpaRepository<Book, Long> {
"where (LOWER(b.title) like %:searchWord% or LOWER(b.author) like %:searchWord%) and ki.name in :names")
Page<Book> findPagingBySearchWordAndKeyword(@Param("searchWord") String searchWord,
@Param("names") List<String> keywordNameList, Pageable pageable);

@Query("select b from Book b inner join ReadExperience re on b.id = re.book.id " +
"join fetch b.middleCategory m " +
"where m.id = :categoryId group by b.id " +
"order by count(re.id) desc")
Slice<Book> findPopularByCategory(@Param("categoryId") Long categoryId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@

public interface InterestRecommendRepository extends JpaRepository<InterestRecommend, Long> {

@EntityGraph(attributePaths = {"book"})
@Query("select ir from InterestRecommend ir join fetch ir.middleCategory mc where mc.id in :categoryIdList")
@Query(value = "select ir.* from book_pharmacy_local.interest_recommend as ir " +
"inner join book_pharmacy_local.book as b on ir.book_id = b.book_id " +
"order by RAND()", nativeQuery = true)
List<InterestRecommend> findRandAll(Pageable pageable);

@Query(value = "select ir.* from book_pharmacy_local.interest_recommend as ir " +
"inner join book_pharmacy_local.book as b on ir.book_id = b.book_id " +
"inner join book_pharmacy_local.categories as c on ir.category_id = c.category_id " +
"where c.category_id in :categoryIdList order by RAND()"
, nativeQuery = true)
List<InterestRecommend> findByInterestList(@Param("categoryIdList") List<Long> categoryIdList, Pageable pageable);
}

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package kr.KWGraduate.BookPharmacy.domain.book.service;

import kr.KWGraduate.BookPharmacy.domain.book.domain.Book;
import kr.KWGraduate.BookPharmacy.domain.book.domain.ClientRecommend;
import kr.KWGraduate.BookPharmacy.domain.book.domain.InterestRecommend;
import kr.KWGraduate.BookPharmacy.domain.book.dto.response.BoardBasedRecommendDto;
import kr.KWGraduate.BookPharmacy.domain.book.dto.response.BookBasedRecommendDto;
import kr.KWGraduate.BookPharmacy.domain.book.dto.response.ClientBasedRecommendDto;
import kr.KWGraduate.BookPharmacy.domain.book.repository.BoardRecommendRepository;
import kr.KWGraduate.BookPharmacy.domain.book.repository.BookRecommendRepository;
import kr.KWGraduate.BookPharmacy.domain.book.repository.ClientRecommendRepository;
import kr.KWGraduate.BookPharmacy.domain.book.repository.InterestRecommendRepository;
import kr.KWGraduate.BookPharmacy.domain.book.repository.*;
import kr.KWGraduate.BookPharmacy.domain.category.domain.Categories;
import kr.KWGraduate.BookPharmacy.domain.category.repository.CategoryRepository;
import kr.KWGraduate.BookPharmacy.domain.client.domain.Client;
import kr.KWGraduate.BookPharmacy.domain.client.repository.ClientRepository;
import kr.KWGraduate.BookPharmacy.domain.interest.domain.Interest;
Expand Down Expand Up @@ -37,6 +37,8 @@ public class RecommendService {
private final InterestRecommendRepository interestRecommendRepository;
private final ClientRepository clientRepository;
private final ReadExperienceRepository readExperienceRepository;
private final CategoryRepository categoryRepository;
private final BookRepository bookRepository;

public List<ClientBasedRecommendDto> getClientBasedAiPrescription(AuthenticationAdapter authentication){
String username = authentication.getUsername();
Expand Down Expand Up @@ -125,17 +127,36 @@ public List<BookBasedRecommendDto> getBookBasedRecommend(String isbn){
.collect(Collectors.toList());
}

// 스케쥴러에 의해 관심사 추천 도서를 등록하는 함수
public void setInterestRecommend() {

interestRecommendRepository.deleteAll();
interestRecommendRepository.flush();

List<Categories> childCategories = categoryRepository.findChildCategories();

PageRequest pageRequest = PageRequest.of(0, 30);

for (Categories category: childCategories) {
Long categoryId = category.getId();
List<Book> popularBookList = bookRepository.findPopularByCategory(categoryId, pageRequest).getContent();
List<InterestRecommend> interestRecommendList = popularBookList.stream()
.map(book -> new InterestRecommend(book)).collect(Collectors.toList());
interestRecommendRepository.saveAll(interestRecommendList);
}
}

private List<InterestRecommend> getInterestRecommend(String username, Pageable pageable) {
List<Interest> interestList = interestRepository.findByLoginId(username); // 유저의 관심사리스트

List<InterestRecommend> interestRecommend;

if(interestList.isEmpty()) // 유저가 관심사를 하나도 등록하지 않았을 경우
{
interestRecommend = interestRecommendRepository.findAll(pageable).getContent();
interestRecommend = interestRecommendRepository.findRandAll(pageable);

}else{
List<Long> interestIdList = interestList.stream().map(interest -> interest.getId()).collect(Collectors.toList());
List<Long> interestIdList = interestList.stream().map(interest -> interest.getCategory().getId()).collect(Collectors.toList());
interestRecommend = interestRecommendRepository.findByInterestList(interestIdList, pageable);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

Expand All @@ -13,5 +14,5 @@ public interface InterestRepository extends JpaRepository<Interest, Long> {
// 유저의 아이디로 관심사를 조회함
@EntityGraph(attributePaths = {"category"})
@Query("select i from Interest i join fetch i.client c where c.loginId = :loginId")
List<Interest> findByLoginId(String loginId);
List<Interest> findByLoginId(@Param("loginId") String loginId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@Table(indexes = {
@Index(name = "read_experience_index", columnList = "book_id, client_id", unique = true) // 중복된 독서경험이 추가되지 않도록 하기 위함
})
public class ReadExperience extends BaseTimeEntity {
public class ReadExperience {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "read_experience_id")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kr.KWGraduate.BookPharmacy.global.common.service;

import kr.KWGraduate.BookPharmacy.domain.book.service.BestSellerBookService;
import kr.KWGraduate.BookPharmacy.domain.book.service.RecommendService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
Expand All @@ -12,9 +13,15 @@
public class BookSchedulerService {

private final BestSellerBookService bestSellerBookService;
private final RecommendService recommendService;

@Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul") // 매일 서울기준, 00시 00분 00초에 실행
public void setBestSeller() {
bestSellerBookService.setBestSellerBooks();
}

@Scheduled(cron = "1 0 0 * * *", zone = "Asia/Seoul") // 매일 서울기준, 00시 00분 00초에 실행
public void setInterestRecommend() {
recommendService.setInterestRecommend();
}
}
2 changes: 1 addition & 1 deletion submodule-config

0 comments on commit 39ef1a0

Please sign in to comment.