diff --git a/backend/src/main/java/com/openisle/controller/CategoryController.java b/backend/src/main/java/com/openisle/controller/CategoryController.java index 4df6f20af..37282bc39 100644 --- a/backend/src/main/java/com/openisle/controller/CategoryController.java +++ b/backend/src/main/java/com/openisle/controller/CategoryController.java @@ -12,6 +12,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @RestController @@ -44,8 +45,11 @@ public class CategoryController { @GetMapping public List list() { - return categoryService.listCategories().stream() - .map(c -> categoryMapper.toDto(c, postService.countPostsByCategory(c.getId()))) + List all = categoryService.listCategories(); + List ids = all.stream().map(Category::getId).toList(); + Map postsCntByCategoryIds = postService.countPostsByCategoryIds(ids); + return all.stream() + .map(c -> categoryMapper.toDto(c, postsCntByCategoryIds.getOrDefault(c.getId(), 0L))) .sorted((a, b) -> Long.compare(b.getCount(), a.getCount())) .collect(Collectors.toList()); } diff --git a/backend/src/main/java/com/openisle/controller/TagController.java b/backend/src/main/java/com/openisle/controller/TagController.java index 72db5eda5..3c7df2421 100644 --- a/backend/src/main/java/com/openisle/controller/TagController.java +++ b/backend/src/main/java/com/openisle/controller/TagController.java @@ -15,6 +15,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @RestController @@ -62,8 +63,11 @@ public class TagController { @GetMapping public List list(@RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "limit", required = false) Integer limit) { - List dtos = tagService.searchTags(keyword).stream() - .map(t -> tagMapper.toDto(t, postService.countPostsByTag(t.getId()))) + List tags = tagService.searchTags(keyword); + List tagIds = tags.stream().map(Tag::getId).toList(); + Map postCntByTagIds = postService.countPostsByTagIds(tagIds); + List dtos = tags.stream() + .map(t -> tagMapper.toDto(t, postCntByTagIds.getOrDefault(t.getId(), 0L))) .sorted((a, b) -> Long.compare(b.getCount(), a.getCount())) .collect(Collectors.toList()); if (limit != null && limit > 0 && dtos.size() > limit) { diff --git a/backend/src/main/java/com/openisle/repository/PostRepository.java b/backend/src/main/java/com/openisle/repository/PostRepository.java index df0905792..d764bb1dd 100644 --- a/backend/src/main/java/com/openisle/repository/PostRepository.java +++ b/backend/src/main/java/com/openisle/repository/PostRepository.java @@ -92,8 +92,14 @@ public interface PostRepository extends JpaRepository { long countByCategory_Id(Long categoryId); + @Query("SELECT c.id, COUNT(p) FROM Post p JOIN p.category c WHERE c.id IN :categoryIds GROUP BY c.id") + List countPostsByCategoryIds(@Param("categoryIds") List categoryIds); + long countDistinctByTags_Id(Long tagId); + @Query("SELECT t.id, COUNT(DISTINCT p) FROM Post p JOIN p.tags t WHERE t.id IN :tagIds GROUP BY t.id") + List countPostsByTagIds(@Param("tagIds") List tagIds); + long countByAuthor_Id(Long userId); @Query("SELECT FUNCTION('date', p.createdAt) AS d, COUNT(p) AS c FROM Post p " + diff --git a/backend/src/main/java/com/openisle/service/PostService.java b/backend/src/main/java/com/openisle/service/PostService.java index 7b2558e43..30a785ce5 100644 --- a/backend/src/main/java/com/openisle/service/PostService.java +++ b/backend/src/main/java/com/openisle/service/PostService.java @@ -31,16 +31,15 @@ import com.openisle.service.EmailSender; import java.time.ZoneId; import java.time.ZoneOffset; -import java.util.List; +import java.util.*; + import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ScheduledFuture; @@ -567,10 +566,31 @@ public class PostService { return postRepository.countByCategory_Id(categoryId); } + public Map countPostsByCategoryIds(List categoryIds) { + Map result = new HashMap<>(); + var dbResult = postRepository.countPostsByCategoryIds(categoryIds); + dbResult.forEach(r -> { + result.put(((Long)r[0]), ((Long)r[1])); + }); + return result; + } + public long countPostsByTag(Long tagId) { return postRepository.countDistinctByTags_Id(tagId); } + public Map countPostsByTagIds(List tagIds) { + Map result = new HashMap<>(); + if (CollectionUtils.isEmpty(tagIds)) { + return result; + } + var dbResult = postRepository.countPostsByTagIds(tagIds); + dbResult.forEach(r -> { + result.put(((Long)r[0]), ((Long)r[1])); + }); + return result; + } + private java.util.List sortByPinnedAndCreated(java.util.List posts) { return posts.stream() .sorted(java.util.Comparator