Skip to content
This repository was archived by the owner on Oct 5, 2025. It is now read-only.

Commit 95c2abb

Browse files
committed
Naver Rating Insert Use Case
1 parent fb907a9 commit 95c2abb

File tree

4 files changed

+142537
-1
lines changed

4 files changed

+142537
-1
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ dependencies {
2626
implementation("org.projectlombok:lombok")
2727
annotationProcessor("org.projectlombok:lombok")
2828
implementation("org.apache.poi:poi-ooxml:5.2.3")
29+
implementation("com.opencsv:opencsv:5.7.1")
2930
implementation("org.apache.commons:commons-text:1.10.0")
3031
runtimeOnly("com.mysql:mysql-connector-j")
3132
testImplementation("org.springframework.boot:spring-boot-starter-test")

src/main/java/com/snowykte0426/minsole/domain/data/entity/DataJpaEntity.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,12 @@ public class DataJpaEntity {
7272
@Column(name = "phone_num")
7373
private String phoneNum;
7474

75+
// 네이버 평점
76+
@Column(name = "naver_rating")
77+
private Double naverRating;
78+
7579
@Builder
76-
public DataJpaEntity(Long id, String serviceId, String orgCode, String manageCode, String bizName, String permitNo, String roadAddr, String jibunAddr, LocalDate applyDate, LocalDate designateDate, String foodType, String mainFood, LocalDateTime lastUpdateDate, String phoneNum) {
80+
public DataJpaEntity(Long id, String serviceId, String orgCode, String manageCode, String bizName, String permitNo, String roadAddr, String jibunAddr, LocalDate applyDate, LocalDate designateDate, String foodType, String mainFood, LocalDateTime lastUpdateDate, String phoneNum, Double naverRating) {
7781
this.id = id;
7882
this.serviceId = serviceId;
7983
this.orgCode = orgCode;
@@ -88,5 +92,6 @@ public DataJpaEntity(Long id, String serviceId, String orgCode, String manageCod
8892
this.mainFood = mainFood;
8993
this.lastUpdateDate = lastUpdateDate;
9094
this.phoneNum = phoneNum;
95+
this.naverRating = naverRating;
9196
}
9297
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package com.snowykte0426.minsole.domain.data.service;
2+
3+
import com.opencsv.CSVReader;
4+
import com.snowykte0426.minsole.domain.data.entity.DataJpaEntity;
5+
import com.snowykte0426.minsole.domain.data.repository.DataJpaRepository;
6+
import jakarta.annotation.PostConstruct;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.apache.commons.text.similarity.JaroWinklerDistance;
10+
import org.springframework.stereotype.Service;
11+
12+
import java.io.BufferedReader;
13+
import java.io.FileInputStream;
14+
import java.io.FileReader;
15+
import java.io.InputStreamReader;
16+
import java.nio.charset.Charset;
17+
import java.util.HashMap;
18+
import java.util.List;
19+
import java.util.Map;
20+
21+
@Service
22+
@RequiredArgsConstructor
23+
@Slf4j
24+
public class CsvRatingUpdater {
25+
26+
private final DataJpaRepository dataJpaRepository;
27+
28+
@PostConstruct
29+
public void updateRatingsFromCsv() {
30+
String csvPath = "/Users/snowykte0426/Programming/BigData-Server/서울관광재단_식당품질정보_20230111.csv"; // CSV 파일 경로
31+
32+
Map<String, Double> csvRatings = loadCsvData(csvPath);
33+
List<DataJpaEntity> dbEntities = dataJpaRepository.findAll();
34+
35+
JaroWinklerDistance jw = new JaroWinklerDistance();
36+
final double THRESHOLD = 0.90; // 유사도 임계값
37+
38+
for (DataJpaEntity entity : dbEntities) {
39+
String bizName = entity.getBizName();
40+
if (bizName == null) continue;
41+
42+
double bestScore = 0.0;
43+
String bestMatch = null;
44+
for (String csvName : csvRatings.keySet()) {
45+
double score = jw.apply(bizName, csvName);
46+
if (score > bestScore) {
47+
bestScore = score;
48+
bestMatch = csvName;
49+
}
50+
}
51+
52+
if (bestScore >= THRESHOLD && bestMatch != null) {
53+
Double rating = csvRatings.get(bestMatch);
54+
entity = DataJpaEntity.builder().
55+
id(entity.getId()).
56+
serviceId(entity.getServiceId()).
57+
orgCode(entity.getOrgCode()).
58+
manageCode(entity.getManageCode()).
59+
bizName(bizName).
60+
permitNo(entity.getPermitNo()).
61+
roadAddr(entity.getRoadAddr()).
62+
jibunAddr(entity.getJibunAddr()).
63+
applyDate(entity.getApplyDate()).
64+
designateDate(entity.getDesignateDate()).
65+
foodType(entity.getFoodType()).
66+
naverRating(rating).
67+
build();
68+
log.info("Updated {} with rating {}", bizName, rating);
69+
}
70+
}
71+
72+
dataJpaRepository.saveAll(dbEntities); // 모든 변경 저장
73+
log.info("네이버 평점 업데이트 완료");
74+
}
75+
76+
private Map<String, Double> loadCsvData(String csvFilePath) {
77+
Map<String, Double> dataMap = new HashMap<>();
78+
try (CSVReader reader = new CSVReader(new InputStreamReader(new FileInputStream(csvFilePath), Charset.forName("EUC-KR")))) {
79+
List<String[]> allLines = reader.readAll();
80+
String[] header = allLines.getFirst(); // 헤더 줄
81+
82+
// "식당명"과 "네이버평점" 컬럼의 인덱스 찾기
83+
int nameIndex = -1;
84+
int ratingIndex = -1;
85+
for (int i = 0; i < header.length; i++) {
86+
if (header[i].equals("식당명")) nameIndex = i;
87+
if (header[i].equals("네이버평점")) ratingIndex = i;
88+
}
89+
if (nameIndex == -1 || ratingIndex == -1) {
90+
throw new RuntimeException("CSV 파일에 '식당명' 또는 '네이버평점' 컬럼이 없습니다.");
91+
}
92+
93+
// 데이터 읽기
94+
for (int i = 1; i < allLines.size(); i++) {
95+
String[] line = allLines.get(i);
96+
if (line.length <= Math.max(nameIndex, ratingIndex)) continue;
97+
98+
String name = line[nameIndex];
99+
String rating = line[ratingIndex];
100+
if (name != null && rating != null) {
101+
dataMap.put(name.trim(), Double.valueOf(rating.trim()));
102+
}
103+
}
104+
} catch (Exception e) {
105+
log.error("CSV 읽기 실패", e);
106+
}
107+
return dataMap;
108+
}
109+
}

0 commit comments

Comments
 (0)