From e43e1bc230385d5d8f897c73eba28791d0a82b8d Mon Sep 17 00:00:00 2001 From: Kyoungwoong Date: Thu, 3 Jul 2025 19:03:14 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refac:=20=EB=89=B4=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=8B=9C=20es=EC=97=90=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++ .../batch/news/entity/NewsDocument.java | 24 +++++++++++ .../news/repository/NewsSearchRepository.java | 14 ++++++ .../batch/news/service/NewsService.java | 43 +++++++++++++++++++ src/main/resources/application.yml | 4 +- 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/playhive/batch/news/entity/NewsDocument.java create mode 100644 src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java diff --git a/build.gradle b/build.gradle index 119ed77..029e3da 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,10 @@ dependencies { implementation group: 'com.mysql', name: 'mysql-connector-j', version: '8.3.0' implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.31.0' + + // ElasticSearch + implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' + implementation 'jakarta.json:jakarta.json-api:2.1.1' } tasks.named('test') { diff --git a/src/main/java/com/playhive/batch/news/entity/NewsDocument.java b/src/main/java/com/playhive/batch/news/entity/NewsDocument.java new file mode 100644 index 0000000..4003fbf --- /dev/null +++ b/src/main/java/com/playhive/batch/news/entity/NewsDocument.java @@ -0,0 +1,24 @@ +package com.playhive.batch.news.entity; + +import jakarta.persistence.Id; +import lombok.*; +import org.springframework.data.elasticsearch.annotations.Document; + +import java.time.LocalDateTime; + +@Document(indexName = "news") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class NewsDocument { + + @Id + private String id; + + private String title; + private String content; + private String category; + private LocalDateTime postDate; +} diff --git a/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java b/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java new file mode 100644 index 0000000..ab574ab --- /dev/null +++ b/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java @@ -0,0 +1,14 @@ +package com.playhive.batch.news.repository; + +import com.playhive.batch.news.entity.NewsDocument; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +public interface NewsSearchRepository extends ElasticsearchRepository { + + // 기본 쿼리: 제목 또는 내용에 키워드 포함 + Page findByTitleContainingOrContentContaining( + String title, String content, Pageable pageable + ); +} diff --git a/src/main/java/com/playhive/batch/news/service/NewsService.java b/src/main/java/com/playhive/batch/news/service/NewsService.java index 7c7e321..08e0b32 100644 --- a/src/main/java/com/playhive/batch/news/service/NewsService.java +++ b/src/main/java/com/playhive/batch/news/service/NewsService.java @@ -1,5 +1,8 @@ package com.playhive.batch.news.service; +import com.playhive.batch.news.entity.NewsDocument; +import com.playhive.batch.news.repository.NewsSearchRepository; +import jakarta.annotation.PostConstruct; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -10,6 +13,8 @@ import lombok.RequiredArgsConstructor; +import java.util.List; + @Service @RequiredArgsConstructor @Transactional @@ -17,10 +22,48 @@ public class NewsService { private final NewsRepository newsRepository; private final NewsCountService newsCountService; + private final NewsSearchRepository newsSearchRepository; + + @PostConstruct + public void setUpES() { + System.out.println("================ 초기화 시작 ==================="); + List allNews = newsRepository.findAll(); + syncToElastic(allNews); + System.out.println("================ 초기화 완료 ==================="); + } + + public void syncToElastic(List newsList) { + int batchSize = 1000; + + for (int i = 0; i < newsList.size(); i += batchSize) { + int end = Math.min(i + batchSize, newsList.size()); + List chunk = newsList.subList(i, end).stream() + .map(news -> NewsDocument.builder() + .id(news.getId().toString()) + .title(news.getTitle()) + .content(news.getContent()) + .category(news.getCategory().name()) + .postDate(news.getPostDate()) + .build()) + .toList(); + + newsSearchRepository.saveAll(chunk); + } + } public void saveNews(NewsSaveRequest newsSaveRequest) { News news = newsRepository.save(newsSaveRequest.toEntity()); newsCountService.saveNewsCount(news); + + NewsDocument doc = NewsDocument.builder() + .id(String.valueOf(news.getId())) + .title(news.getTitle()) + .content(news.getContent()) + .category(news.getCategory().name()) + .postDate(news.getPostDate()) + .build(); + + newsSearchRepository.save(doc); } public String findRecentPostDate(NewsCategory category) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9be3a96..2168bbb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -15,7 +15,6 @@ spring: hikari: maximum-pool-size: 20 - jpa: show-sql: false properties: @@ -32,6 +31,9 @@ spring: # none 기존테이블을 더 이상 건드리지 않음. open-in-view: true + elasticsearch: + uris: http://{es-server-ip}:9200 + logging: level: root: info # 전체 로그를 INFO, DEBUG, WARN 수준으로 설정 From e1917d66ce29b12ed0b4ab698f2861096832852f Mon Sep 17 00:00:00 2001 From: Kyoungwoong Date: Thu, 3 Jul 2025 19:09:19 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=EC=9D=98=EB=AF=B8=EC=97=86=EB=8A=94?= =?UTF-8?q?=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../batch/news/repository/NewsSearchRepository.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java b/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java index ab574ab..db0c99a 100644 --- a/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java +++ b/src/main/java/com/playhive/batch/news/repository/NewsSearchRepository.java @@ -6,9 +6,5 @@ import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; public interface NewsSearchRepository extends ElasticsearchRepository { - - // 기본 쿼리: 제목 또는 내용에 키워드 포함 - Page findByTitleContainingOrContentContaining( - String title, String content, Pageable pageable - ); + }