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

해시태그 팔로우 구현, 검색 API 개선 #145

Merged
merged 9 commits into from
Mar 22, 2022
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cloneproject.Instagram.controller;

import cloneproject.Instagram.dto.hashtag.HashtagDTO;
import cloneproject.Instagram.dto.post.PostDTO;
import cloneproject.Instagram.dto.result.ResultResponse;
import cloneproject.Instagram.service.HashtagService;
Expand Down Expand Up @@ -49,38 +48,18 @@ public ResponseEntity<ResultResponse> getHashtagPosts(
return ResponseEntity.ok(ResultResponse.of(GET_HASHTAG_POSTS_SUCCESS, response));
}

@ApiOperation(value = "해시태그 연관 검색어 목록 페이징 조회")
@ApiImplicitParams({
@ApiImplicitParam(name = "page", value = "page", example = "1", required = true),
@ApiImplicitParam(name = "size", value = "size", example = "10", required = true),
@ApiImplicitParam(name = "hashtag", value = "hashtag", example = "만두", required = true)
})
@GetMapping("/hashtags")
public ResponseEntity<ResultResponse> getHashtags(
@NotNull(message = "page는 필수입니다.") @RequestParam int page,
@NotNull(message = "size는 필수입니다.") @RequestParam int size,
@NotBlank(message = "hashtag는 필수입니다.") @RequestParam String hashtag) {
final Page<HashtagDTO> response = hashtagService.getHashTagsLikeName(page, size, hashtag.substring(1));

return ResponseEntity.ok(ResultResponse.of(GET_HASHTAGS_SUCCESS, response));
}

@ApiOperation(value = "해시태그 팔로우")
@ApiImplicitParam(name = "hashtag", value = "hashtag", example = "만두", required = true)
@PostMapping("/hashtags/follow")
public ResponseEntity<ResultResponse> followHashtag(
@NotBlank(message = "hashtag는 필수입니다.") @RequestParam String hashtag) {

public ResponseEntity<ResultResponse> followHashtag(@NotBlank(message = "hashtag는 필수입니다.") @RequestParam String hashtag) {
hashtagService.followHashtag(hashtag);
return ResponseEntity.ok(ResultResponse.of(FOLLOW_HASHTAG_SUCCESS, null));
}

@ApiOperation(value = "해시태그 언팔로우")
@ApiImplicitParam(name = "hashtag", value = "hashtag", example = "만두", required = true)
@DeleteMapping("/hashtags/follow")
public ResponseEntity<ResultResponse> unfollowHashtag(
@NotBlank(message = "hashtag는 필수입니다.") @RequestParam String hashtag) {

public ResponseEntity<ResultResponse> unfollowHashtag(@NotBlank(message = "hashtag는 필수입니다.") @RequestParam String hashtag) {
hashtagService.unfollowHashtag(hashtag);
return ResponseEntity.ok(ResultResponse.of(UNFOLLOW_HASHTAG_SUCCESS, null));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import cloneproject.Instagram.service.SearchService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -39,21 +40,14 @@ public ResponseEntity<ResultResponse> searchText(@RequestParam String text) {
return new ResponseEntity<>(result, HttpStatus.valueOf(result.getStatus()));
}

@ApiOperation(value = "유저 검색 조회수 증가")
@ApiImplicitParam(name = "username", value = "조회수 증가시킬 username", required = true, example = "dlwlrma")
@ApiOperation(value = "검색 조회수 증가")
@ApiImplicitParams({
@ApiImplicitParam(name = "entityName", value = "조회수 증가시킬 식별 name", required = true, example = "dlwlrma"),
@ApiImplicitParam(name = "entityType", value = "조회수 증가시킬 type", required = true, example = "MEMBER")
})
@PostMapping(value = "/topsearch/member/upcount")
seonpilKim marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<ResultResponse> increaseSearchMemberCount(@RequestParam String username) {
searchService.increaseSearchMemberCount(username);

ResultResponse result = ResultResponse.of(ResultCode.INCREASE_SEARCH_COUNT_SUCCESS, null);
return new ResponseEntity<>(result, HttpStatus.valueOf(result.getStatus()));
}

@ApiOperation(value = "해시태그 검색 조회수 증가")
@ApiImplicitParam(name = "name", value = "조회수 증가시킬 hashtag", required = true, example = "만두")
@PostMapping(value = "/topsearch/hashtag/upcount")
public ResponseEntity<ResultResponse> increaseSearchHashtagCount(@RequestParam String name) {
searchService.increaseSearchHashtagCount(name);
public ResponseEntity<ResultResponse> increaseSearchMemberCount(@RequestParam String entityName, @RequestParam String entityType) {
searchService.increaseSearchCount(entityName, entityType);

ResultResponse result = ResultResponse.of(ResultCode.INCREASE_SEARCH_COUNT_SUCCESS, null);
return new ResponseEntity<>(result, HttpStatus.valueOf(result.getStatus()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
seonpilKim marked this conversation as resolved.
Show resolved Hide resolved
public class SearchDTO {
public abstract class SearchDTO {

private String dtype;

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.Optional;
import java.util.Set;

public interface HashtagRepository extends JpaRepository<Hashtag, Long>, HashTagRepositoryQuerydsl {
public interface HashtagRepository extends JpaRepository<Hashtag, Long> {

List<Hashtag> findAllByNameIn(Set<String> names);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package cloneproject.Instagram.repository.search;

import java.util.List;
import java.util.Optional;

import cloneproject.Instagram.entity.hashtag.Hashtag;
import org.springframework.data.jpa.repository.JpaRepository;

import cloneproject.Instagram.entity.search.SearchHashtag;

public interface SearchHashtagRepository extends JpaRepository<SearchHashtag, Long>{
public interface SearchHashtagRepository extends JpaRepository<SearchHashtag, Long> {

Optional<SearchHashtag> findByHashtagName(String name);

List<SearchHashtag> findAllByHashtagIn(List<Hashtag> hashtags);
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public List<SearchDTO> searchByText(Long loginedId, String text){

// follow 주입
final List<String> resultUsernames = memberMap.values().stream().map(s -> s.getMemberDTO().getUsername())
.collect(Collectors.toList());
.collect(Collectors.toList());

// TODO 우선 이전의 search에 있던 코드 그대로 넣었는데 개선 필요해보임 !
memberMap.forEach((id, member) -> {
Expand Down Expand Up @@ -125,16 +125,11 @@ public List<SearchDTO> searchByText(Long loginedId, String text){
))
);

boolean matchingMemberExists = queryFactory
.from(searchMember)
.innerJoin(searchMember.member, member).fetchJoin()
.where(searchMember.id.in(searchIds).and(searchMember.member.username.eq(text)))
.fetchFirst() != null;
boolean matchingHashtagExists = queryFactory
.from(searchHashtag)
.innerJoin(searchHashtag.hashtag, hashtag).fetchJoin()
.where(searchHashtag.id.in(searchIds).and(searchHashtag.hashtag.name.eq(text)))
.fetchFirst() != null;
final List<String> resultHashtagNames = hashtagMap.values().stream().map(h -> h.getName())
.collect(Collectors.toList());

boolean matchingMemberExists = resultUsernames.contains(text);
boolean matchingHashtagExists = resultHashtagNames.contains(text);

final List<SearchDTO> searchDTOs = searches.stream()
.map(search -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cloneproject.Instagram.service;

import cloneproject.Instagram.dto.hashtag.HashtagDTO;
import cloneproject.Instagram.dto.post.PostDTO;
import cloneproject.Instagram.entity.hashtag.Hashtag;
import cloneproject.Instagram.entity.member.HashtagFollow;
Expand Down Expand Up @@ -47,12 +46,6 @@ public Page<PostDTO> getHashTagPosts(int page, int size, String name) {
return postRepository.findPostDtoPageByHashtag(pageable, member, findHashtag.get());
}

public Page<HashtagDTO> getHashTagsLikeName(int page, int size, String name) {
page = (page == 0 ? 0 : page - 1);
final Pageable pageable = PageRequest.of(page, size);
return hashtagRepository.findHashtagDtoPageLikeName(pageable, name);
}

@Transactional
public void followHashtag(String hashtagName){
String memberId = SecurityContextHolder.getContext().getAuthentication().getName();
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/cloneproject/Instagram/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class PostService {
private final JoinRoomRepository joinRoomRepository;
private final HashtagRepository hashtagRepository;
private final HashtagPostRepository hashtagPostRepository;
private final SearchService searchService;

public Page<PostDTO> getPostDtoPage(int size, int page) {
page = (page == 0 ? 0 : page - 1) + 10;
Expand Down Expand Up @@ -403,13 +404,14 @@ private void registerHashtags(Post post, String content) {
.collect(Collectors.toMap(Hashtag::getName, h -> h));
final List<HashtagPost> newHashtagPost = new ArrayList<>();
names.forEach(name -> {
Hashtag hashtag;
final Hashtag hashtag;
if (hashtagMap.containsKey(name)) {
hashtag = hashtagMap.get(name);
hashtag.upCount();
}
else
} else {
hashtag = hashtagRepository.save(new Hashtag(name));
searchService.createSearchHashtag(hashtag);
}
newHashtagPost.add(new HashtagPost(hashtag, post));
});
hashtagPostRepository.saveAllBatch(newHashtagPost);
Expand All @@ -429,6 +431,7 @@ private void unregisterHashtags(Post post) {
final List<HashtagPost> hashtagPosts = hashtagPostRepository.findAllByHashtagIn(deleteHashtags);
hashtagPostRepository.deleteAllInBatch(hashtagPosts);
hashtagRepository.deleteAllInBatch(deleteHashtags);
searchService.deleteSearchHashtags(deleteHashtags);
}

public Page<CommentDTO> getCommentDtoPage(Long postId, int page) {
Expand Down
45 changes: 29 additions & 16 deletions src/main/java/cloneproject/Instagram/service/SearchService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package cloneproject.Instagram.service;


import java.util.List;
import java.util.stream.Collectors;

import cloneproject.Instagram.entity.hashtag.Hashtag;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -20,37 +21,49 @@
@Service
@RequiredArgsConstructor
public class SearchService {

private final SearchRepository searchRepository;
private final SearchMemberRepository searchMemberRepository;
private final SearchHashtagRepository searchHashtagRepository;

@Transactional(readOnly = true)
public List<SearchDTO> searchByText(String text){
public List<SearchDTO> searchByText(String text) {
final String memberId = SecurityContextHolder.getContext().getAuthentication().getName();
List<SearchDTO> result;
if(text.charAt(0) == '#'){
final List<SearchDTO> result;
if (text.charAt(0) == '#') {
result = searchRepository.searchByTextOnlyHashtag(Long.valueOf(memberId), text.substring(1));
}else{
} else {
result = searchRepository.searchByText(Long.valueOf(memberId), text);
}
return result;
}

@Transactional
public void increaseSearchMemberCount(String username){
SearchMember searchMember = searchMemberRepository.findByMemberUsername(username)
.orElseThrow(MemberDoesNotExistException::new);
searchMember.upCount();
searchMemberRepository.save(searchMember);
public void increaseSearchCount(String entityName, String entityType) {
switch(entityType){
case "MEMBER":
SearchMember searchMember = searchMemberRepository.findByMemberUsername(entityName)
.orElseThrow(MemberDoesNotExistException::new);
searchMember.upCount();
searchMemberRepository.save(searchMember);
break;
case "HASHTAG":
SearchHashtag searchHashtag = searchHashtagRepository.findByHashtagName(entityName)
.orElseThrow(HashtagNotFoundException::new);
searchHashtag.upCount();
searchHashtagRepository.save(searchHashtag);
break;
}
}

@Transactional
public void increaseSearchHashtagCount(String name){
SearchHashtag searchHashtag = searchHashtagRepository.findByHashtagName(name)
.orElseThrow(HashtagNotFoundException::new);
searchHashtag.upCount();
searchHashtagRepository.save(searchHashtag);
public void createSearchHashtag(Hashtag hashtag) {
searchHashtagRepository.save(new SearchHashtag(hashtag));
}

@Transactional
public void deleteSearchHashtags(List<Hashtag> hashtags) {
final List<SearchHashtag> searchHashtags = searchHashtagRepository.findAllByHashtagIn(hashtags);
searchHashtagRepository.deleteAllInBatch(searchHashtags);
}
}