diff --git a/Backend/src/main/java/com/example/demo/controller/userRecommendCalc/UserRecommendController.java b/Backend/src/main/java/com/example/demo/controller/userRecommendCalc/UserRecommendController.java index f58174a..b219445 100644 --- a/Backend/src/main/java/com/example/demo/controller/userRecommendCalc/UserRecommendController.java +++ b/Backend/src/main/java/com/example/demo/controller/userRecommendCalc/UserRecommendController.java @@ -1,6 +1,7 @@ package com.example.demo.controller.userRecommendCalc; import com.example.demo.response.CommonResponse; +import com.example.demo.service.recommendCalc.Recommend; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -9,14 +10,35 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; @AllArgsConstructor @RestController public class UserRecommendController { @GetMapping("/user/project/manage/recommend") - public void recommendUser(@RequestBody Long project_id, String stackName) { + public List recommendUser(@RequestBody Long project_id, String stackName) { + int proj_id=(int)project_id.longValue(); + List result= Recommend.projectBaseSearch(proj_id,stackName); + List resultAsLong = result.stream() + .map(Long::valueOf) + .collect(Collectors.toList()); + + return resultAsLong; } -} + + public List recommendTeam(@RequestBody Long user_id, String stackName) { + int userId=(int)user_id.longValue(); + + List result= Recommend.userBaseSearch(userId,stackName); + + List resultAsLong = result.stream() + .map(Long::valueOf) + .collect(Collectors.toList()); + + return resultAsLong; + } + +} \ No newline at end of file diff --git a/Backend/src/main/java/com/example/demo/service/recommendCalc/AccessDB.java b/Backend/src/main/java/com/example/demo/service/recommendCalc/AccessDB.java index 9aae3ca..47916d5 100644 --- a/Backend/src/main/java/com/example/demo/service/recommendCalc/AccessDB.java +++ b/Backend/src/main/java/com/example/demo/service/recommendCalc/AccessDB.java @@ -1,8 +1,11 @@ package com.example.demo.service.recommendCalc; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Service; +import javax.annotation.PostConstruct; import java.sql.*; import java.util.ArrayList; import java.util.Arrays; @@ -11,197 +14,383 @@ @Service public class AccessDB { + + private static String jdbcUrl; + private static String DBusername; + private static String DBpassword; + @Value("${spring.datasource.url}") - String jdbcUrl; + public void setJdbcUrl(String jdbcUrl){ + AccessDB.jdbcUrl=jdbcUrl; + } @Value("${spring.datasource.username}") - String DBusername; + public void setDBusername(String dBusername){ + AccessDB.DBusername=dBusername; + } @Value("${spring.datasource.password}") - String DBpassword; - -// static float getTeamScore(int projId){ -// float avgScore = 0; -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT COUNT(*) AS data_count, SUM(user_role_score) AS score_sum " + -// "FROM project_member " + -// "WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// if (resultSet.next()) { -// float dataCount = resultSet.getFloat("data_count"); -// float scoreSum = resultSet.getFloat("score_sum"); -// -// System.out.println("데이터 개수: " + dataCount); -// System.out.println("user_role_score 합계: " + scoreSum); -// -// avgScore=scoreSum/dataCount; -// -// return avgScore; -// -// } else { -// System.out.println("일치하는 데이터가 없습니다."); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// return 0; -// } -// -// static List stacks = Arrays.asList( -// ".NET", "ASP.NET", "Angular", "AngularJS", "Apache Spark", "Blazor", "C", "C#", -// "C++", "Dart", "Django", "Electron", "Express", "Flask", "Flutter", "Go", -// "HTML/CSS", "Java", "JavaScript", "jQuery", "Keras", "Kotlin", "Laravel", "Lua", -// "NestJS", "Next.js", "Node.js", "OpenGL", "Opencv", "PHP", "Pandas", "PyTorch", -// "Python", "Qt", "R", "RabbitMQ", "React", "React Native", "Ruby", "Ruby on Rails", -// "Rust", "scikit-Learn", "SpringBoot", "Svelte", "Swift", "SwiftUI", "TensorFlow", -// "Torch", "TypeScript", "Vue.js" -// ); -// -// static List getUserAvailableStack(int userId){ -// String stacks_user=""; -// List requiredStack= new ArrayList<>(); -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM user WHERE id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, userId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_user = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// for(int i=0;i<50;i++){ -// if(stacks_user.length()==50){ -// if(stacks_user.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// } -// -// return requiredStack; -// } -// -// static List getProjRequiredStack(int projId){ -// String stacks_front=""; -// String stacks_back=""; -// String stacks_etc=""; -// List requiredStack= new ArrayList<>(); -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM project_front WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_front = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM project_back WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_back = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM project_etc WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_etc = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// for(int i=0;i<50;i++){ -// if(stacks_front.length()==50){ -// if(stacks_front.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// -// if(stacks_back.length()==50){ -// if(stacks_back.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// -// if(stacks_etc.length()==50){ -// if(stacks_etc.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// } -// -// return requiredStack; -// } -// -// static float getUserStackScore(int userId, String stack){ -// float stackscore=0; -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT score FROM "+ stack +" WHERE userId = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, userId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_front = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// return stackscore; -// } -} + public void setDBpassword(String dBpassword){ + AccessDB.DBpassword=dBpassword; + } + + static float getTeamScore(int projId){ + float avgScore = 0; + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT COUNT(*) AS data_count, SUM(user_role_score) AS score_sum " + + "FROM project_member " + + "WHERE project_id = ?"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + if (resultSet.next()) { + float dataCount = resultSet.getFloat("data_count"); + float scoreSum = resultSet.getFloat("score_sum"); + + //System.out.println("데이터 개수: " + dataCount); + //System.out.println("user_role_score 합계: " + scoreSum); + + avgScore=scoreSum/dataCount; + + return avgScore; + + } else { + System.out.println("일치하는 데이터가 없습니다."); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return 0; + } + + static List stacks = Arrays.asList( + ".NET", "ASP.NET", "Angular", "AngularJS", "Apache Spark", "Blazor", "C", "C#", + "C++", "Dart", "Django", "Electron", "Express", "Flask", "Flutter", "Go", + "HTML/CSS", "Java", "JavaScript", "jQuery", "Keras", "Kotlin", "Laravel", "Lua", + "NestJS", "Next.js", "Node.js", "OpenGL", "Opencv", "PHP", "Pandas", "PyTorch", + "Python", "Qt", "R", "RabbitMQ", "React", "React Native", "Ruby", "Ruby on Rails", + "Rust", "scikit-Learn", "SpringBoot", "Svelte", "Swift", "SwiftUI", "TensorFlow", + "Torch", "TypeScript", "Vue.js" + ); + + static List stacksForDB = Arrays.asList( + "dot_net", "asp_net", "angular", "angular_js", "apache_spark", "blazor", "c", "c_sharp", + "cpp", "dart", "django", "electron", "express", "flask", "flutter", "go", + "html_css", "java", "java_script", "jquery", "keras", "kotlin", "laravel", "lua", + "nest_js", "next_js", "node_js", "open_gl", "open_cv", "php", "pandas", "py_torch", + "python", "qt", "r", "rabbit_mq", "react", "react_native", "ruby", "ruby_on_rails", + "rust", "scikit_Learn", "spring_boot", "svelte", "swift", "swift_ui", "tensor_flow", + "torch", "type_script", "vue_js" + ); + + public static String findStackForDB(String stack) { + // 입력으로 주어진 stack이 stacks에 있는지 확인 + int index = stacks.indexOf(stack); + + if (index != -1 && index < stacksForDB.size()) { + // 해당하는 index의 stacksForDB의 값을 반환 + return stacksForDB.get(index); + } else { + // 해당하는 stack이 stacks에 없거나 index가 범위를 벗어나면 null을 반환 + return null; + } + } + + static List getUserAvailableStack(int userId){ + String stacks_user=""; + + List requiredStack=new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM user WHERE id = ?"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, userId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_user = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + for(int i=0;i<50;i++){ + if(stacks_user.length()==50){ + if(stacks_user.charAt(i)=='8'){ + String[] data= new String[2]; + data[0]=stacks.get(i); + data[1]=stacksForDB.get(i); + requiredStack.add(data); + } + } + } + + return requiredStack; + } + + static List getProjRequiredStack(int projId){ + String stacks_front=""; + String stacks_back=""; + String stacks_etc=""; + + List requiredStack=new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM project_front WHERE project_id = ?"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_front = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM project_back WHERE project_id = ?"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_back = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM project_etc WHERE project_id = ?"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_etc = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + for(int i=0;i<50;i++){ + if(stacks_front.length()==50){ + if(stacks_front.charAt(i)=='8'){ + String[] data= new String[2]; + data[0]=stacks.get(i); + data[1]=stacksForDB.get(i); + requiredStack.add(data); + } + } + + if(stacks_back.length()==50){ + if(stacks_back.charAt(i)=='8'){ + String[] data= new String[2]; + data[0]=stacks.get(i); + data[1]=stacksForDB.get(i); + requiredStack.add(data); + } + } + + if(stacks_etc.length()==50){ + if(stacks_etc.charAt(i)=='8'){ + String[] data= new String[2]; + data[0]=stacks.get(i); + data[1]=stacksForDB.get(i); + requiredStack.add(data); + } + } + } + + return requiredStack; + } + + static float getUserStackScore(int userId, String stack){ + float stackscore=0; + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT score FROM "+ stack +" WHERE user_id = ?"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, userId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + stackscore=resultSet.getFloat("score"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return stackscore; + } + + static ArrayList getStackUserId(String stack){ + ArrayList userId = new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT user_id FROM "+ stack; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + userId.add(resultSet.getInt("user_id")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return userId; + } + + static ArrayList getAllProjectId(){ + ArrayList projId = new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT id FROM project"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + projId.add(resultSet.getInt("id")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return projId; + } + static boolean checkIsRecruiting(int projId, String stack){ + String stacks_front=""; + String stacks_back=""; + String stacks_etc=""; + + boolean avail=false; + + List requiredStack=new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM project_front WHERE project_id = ? AND (required_member - current_member) >= 1"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_front = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM project_back WHERE project_id = ? AND (required_member - current_member) >= 1"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_back = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { + // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 + String sql = "SELECT stacks FROM project_etc WHERE project_id = ? AND (required_member - current_member) >= 1"; + + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setInt(1, projId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + // stacks 값을 가져오기 + stacks_etc = resultSet.getString("stacks"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + for(int i=0;i<50;i++){ + if(stacks_front.length()==50){ + if(stacks_front.charAt(i)=='8'){ + if(stacks.get(i).equals(stack)){ + avail=true; + } + } + } + + if(stacks_back.length()==50){ + if(stacks_back.charAt(i)=='8'){ + if(stacks.get(i).equals(stack)){ + avail=true; + } + } + } + + if(stacks_etc.length()==50){ + if(stacks_etc.charAt(i)=='8'){ + if(stacks.get(i).equals(stack)){ + avail=true; + } + } + } + } + + return avail; + + + } + + +} \ No newline at end of file diff --git a/Backend/src/main/java/com/example/demo/service/recommendCalc/GetDistance.java b/Backend/src/main/java/com/example/demo/service/recommendCalc/GetDistance.java index 13dd2b3..8a7fcf9 100644 --- a/Backend/src/main/java/com/example/demo/service/recommendCalc/GetDistance.java +++ b/Backend/src/main/java/com/example/demo/service/recommendCalc/GetDistance.java @@ -1,45 +1,49 @@ package com.example.demo.service.recommendCalc; -import org.neo4j.driver.*; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Value; - -import java.lang.Record; +import org.neo4j.driver.AuthTokens; +import org.neo4j.driver.Driver; +import org.neo4j.driver.GraphDatabase; +import org.neo4j.driver.Record; +import org.neo4j.driver.Result; +import org.neo4j.driver.Session; @Service public class GetDistance { + @Value("${security.neo4j.uri}") - String neo4jUri; + private static String neo4jUri; @Value("${security.neo4j.user}") - String neo4jUser; + private static String neo4jUser; @Value("${security.neo4j.password}") - String neo4jPassword; - -// public static float getDistance(String stack1, String stack2){ -// -// float distance=0; -// -// try (Driver driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password)); -// Session session = driver.session()) { -// String start="MATCH path=allShortestPaths((startNode:techStack {techStack: '"; -// String middle="'})-[:relation*..10]-(endNode:techStack {techStack: '"; -// String end="'}))" + -// "RETURN REDUCE(s = 0, rel IN relationships(path) | s + rel.weight) AS totalWeight"; -// -// String query=start+stack1+middle+stack2+end; -// -// Result result = session.run(query); -// -// Record record = result.next(); -// Value totalWeight = record.get("totalWeight"); -// System.out.println("Total Weight: " + totalWeight.asDouble()); -// distance=totalWeight.asFloat(); -// -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return distance; -// } -} + private static String neo4jPassword; + + + public static float getDistance(String stack1, String stack2){ + + float distance=0; + + try (Driver driver = GraphDatabase.driver(neo4jUri, AuthTokens.basic(neo4jUser, neo4jPassword)); + Session session = driver.session()) { + String start="MATCH path=allShortestPaths((startNode:techStack {techStack: '"; + String middle="'})-[:relation*..10]-(endNode:techStack {techStack: '"; + String end="'}))" + + "RETURN REDUCE(s = 0, rel IN relationships(path) | s + rel.weight) AS totalWeight"; + + String query=start+stack1+middle+stack2+end; + + Result result = session.run(query); + + Record record = result.next(); + org.neo4j.driver.Value totalWeight = record.get("totalWeight"); + distance=totalWeight.asFloat(); + + } catch (Exception e) { + e.printStackTrace(); + } + return distance; + } +} \ No newline at end of file diff --git a/Backend/src/main/java/com/example/demo/service/recommendCalc/Recommend.java b/Backend/src/main/java/com/example/demo/service/recommendCalc/Recommend.java index 9222dbf..3339f4e 100644 --- a/Backend/src/main/java/com/example/demo/service/recommendCalc/Recommend.java +++ b/Backend/src/main/java/com/example/demo/service/recommendCalc/Recommend.java @@ -1,193 +1,143 @@ package com.example.demo.service.recommendCalc; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; import java.util.*; +import static java.lang.Math.abs; + +@Transactional +@Service public class Recommend { -// public void projectBaseSearch(int teamId, String stack){ -// float teamScore=AccessDB.getTeamScore(teamId); -// List projectRequiredStack =AccessDB.getProjRequiredStack(teamId); -// -// -// -// -// -// } -// -// public static void main(String[] args) { -// float a = AccessDB.getTeamScore(2); -// System.out.println("getTeamScore() 테스트 : " + a); -// -// List requiredStack = AccessDB.getProjRequiredStack(2); -// -// System.out.println(requiredStack); -// -// -///* -// float b = urs.calculateUrs(123,456,"Java"); -// System.out.println("calculateUrs() 테스트 : " + b); -// -// System.out.println("\n--- getUsers() --------------------------------------------\n"); -// -// int result1[] = getUsers(20, 10, 1, "Java"); -// -// for(int i = 0; i < result1.length; i++){ -// System.out.println("최종 추천 리스트 > " + i + ", userId : " + Math.round(result1[i])); -// } -// -// System.out.println("\n--- getProjs() --------------------------------------------\n"); -// -// int result2[] = getProjs(20, 10, 1, "Java"); -// -// for(int i = 0; i < result2.length; i++){ -// System.out.println("최종 추천 리스트 > " + i + ", projectId : " + Math.round(result2[i])); -// } -// */ -// } -// -// // 프로젝트 팀장이 특정 기술 스택에 대하여 팀원을 추천 받는 메소드 (output: 추천 팀원들의 userId 배열) -// static int[] getUsers(int sampleSize, int recommendSize, int projId, String targetStack){ -// Random random = new Random(); //테스트 데이터셋 생성을 위한 Random 객체 생성 -// -// float avgScore = 3 + random.nextFloat() * (10 - 3); //PROJECT_INFO.avg_score(id=proj_id) 테스트 데이터셋 생성 -// int testSize = 100; //테스트를 위한 targetStack 테이블의 데이터 수 -// float proficiency[][] = new float[testSize][2]; // 숙련도 테이블 데이터가 저장되는 배열 -// float gapsProjUsers[][] = new float[testSize][3]; //유저의 데이터와 |PROJECT_INFO.avg_score(id=proj_id) - .proficiency|값이 저장되는 배열 -// float selectedUsers[][] = new float[sampleSize][2]; //최종 상위 추천 유저의 데이터가 recommendSize만큼 저장되는 배열 -// int result[] = new int[recommendSize]; //getUsers() 함수 최종 출력값 (userId) -// -// //구현 1: 에서 |PROJECT_INFO.avg_score(id=proj_id) - .proficiency|의 값이 작은 순으로 sampleSize만큼 추출 ------------- -// //1000부터 9999까지 겹치지 않는 testSize개의 수 생성 -// Set uniqueNumbers = new HashSet<>(); -// while (uniqueNumbers.size() < testSize) { -// int randomNumber = random.nextInt(9000) + 1000; -// uniqueNumbers.add(randomNumber); -// } -// -// int i = 0; -// //.proficiency 테스트 데이터셋 생성 -// for (int user_id : uniqueNumbers) { -// proficiency[i][0] = user_id; -// proficiency[i][1] = 3 + random.nextFloat() * (10 - 3); -// System.out.println(i + ", userId : " + Math.round(proficiency[i][0]) + ", 숙련도 : " + proficiency[i][1]); -// i+=1; -// } -// System.out.println("\n"); -// -// //|avgUrs - .proficiency|를 구하여 sampleSize만큼 샘플링 -// for(i = 0; i < testSize; i++){ -// gapsProjUsers[i][0] = proficiency[i][0]; -// gapsProjUsers[i][1] = Math.abs(avgScore-proficiency[i][1]); -// gapsProjUsers[i][2] = proficiency[i][1]; -// System.out.println(i + ", userId : " + Math.round(gapsProjUsers[i][0]) + ", |avgUrs - 숙련도| : " + gapsProjUsers[i][1]); -// } -// System.out.println("\n"); -// -// Arrays.sort(gapsProjUsers, Comparator.comparingDouble(arr -> arr[1])); -// -// for(i = 0; i < sampleSize; i++){ -// System.out.println("정렬됨 > " + i + ", userId : " + Math.round(gapsProjUsers[i][0]) + ", |avgUrs - 숙련도| : " + gapsProjUsers[i][1]); -// } -// System.out.println("\n"); -// //-------------------------------------------------------------------------------------------------------------------------------------------- -// -// //구현 2: 이전 단계에서 구한 상위 sampleSize개의 샘플들에 대해서 모두 calculateUrs()를 이용해 urs를 구함 --------------------------------------------------------------------- -// for(i = 0; i < sampleSize; i++){ -// selectedUsers[i][0] = gapsProjUsers[i][0]; -// selectedUsers[i][1] = gapsProjUsers[i][2] + random.nextFloat() * 1.5f; //원래는 calculateUrs() 함수를 사용하여 urs를 구해야 하지만 DB 완성 전까지는 이와 같은 방식으로 대체 -// System.out.println(i + ", user_id : " + Math.round(selectedUsers[i][0]) + ", urs : " + selectedUsers[i][1]); -// } -// System.out.println("\n"); -// //-------------------------------------------------------------------------------------------------------------------------------------------- -// -// //구현 3: |selectedUsers[][1]-PROJECT_INFO.avg_score(id=proj_id)|의 값이 작은 순으로 recommendSize만큼 추출 ----------------------------------------- -// for(i = 0; i < sampleSize; i++){ -// selectedUsers[i][1] = Math.abs(selectedUsers[i][1]-avgScore); -// } -// -// Arrays.sort(selectedUsers, Comparator.comparingDouble(arr -> arr[1])); -// -// for(i = 0; i < recommendSize; i++){ -// result[i] = Math.round(selectedUsers[i][0]); -// System.out.println("정렬됨 > " + i + ", user_id : " + Math.round(selectedUsers[i][0]) + ", |urs - avgUrs| : " + selectedUsers[i][1]); -// } -// System.out.println("\n"); -// //--------------------------------------------------------------------------------------------------------------------------------------------- -// -// return result; -// } -// -// // 유저가 특정 기술 스택에 대하여 프로젝트를 추천 받는 메소드 (output: 추천 팀원들의 projId 배열) -// static int[] getProjs(int sampleSize, int recommendSize, int userId, String targetStack){ -// Random random = new Random(); //테스트 데이터셋 생성을 위한 Random 객체 생성 -// -// float proficiency = 3 + random.nextFloat() * (10 - 3); //.proficienct(id=proj_id) 테스트 데이터 생성 -// System.out.println("userId proficiency : " + proficiency + "\n"); -// int testSize = 50; //테스트를 위한 targetStack 테이블의 데이터 수 -// float recruitingProjs[] = new float[testSize]; //PROJECT_SPEC에서 targetStack에 대해서 모집 중인 프로젝트들의 ProjId가 저장되는 배열 -// float gapsProjUsers[][] = new float[testSize][2]; //유저의 데이터와 |PROJECT_INFO.avg_score(id=proj_id) - .proficiency|값이 저장되는 배열 -// float selectedProjs[][] = new float[sampleSize][3]; //최종 상위 추천 유저의 데이터가 recommendSize만큼 저장되는 배열 -// int result[] = new int[recommendSize]; //getProjs() 함수 최종 출력값 (projectId) -// -// //구현 1: PROJECT_SPEC에서 using_stack이 targetStack이면서 is_recruited가 0인 프로젝트의 projectId 추출 (중복 제거 필요) --------------------------- -// //100부터 999까지 겹치지 않는 testSize개의 수 생성 -// Set uniqueNumbers = new HashSet<>(); -// while (uniqueNumbers.size() < testSize) { -// int randomNumber = random.nextInt(900) + 100; -// uniqueNumbers.add(randomNumber); -// } -// -// int i = 0; -// //PROJECT_SPEC에서 targetStack에 대해서 모집 중인 프로젝트들에 대한 테스트 데이터셋 생성 -// for (int proj_id : uniqueNumbers) { -// recruitingProjs[i] = proj_id; -// System.out.println(targetStack + " 테이블 > " + i + ", projId : " + Math.round(recruitingProjs[i])); -// i+=1; -// } -// System.out.println("\n"); -// //------------------------------------------------------------------------------------------------------------------------------------- -// -// //구현 2: recruitingProjs[]의 프로젝트들 중 |PROJECT_INFO.avg_score - .proficiency(id=user_id)|의 값이 작은 순으로 sampleSize만큼 추출-------------------- -// //|PROJECT_INFO.avg_score - .proficiency(id=user_id)|를 구하여 sampleSize만큼 샘플링 -// for(i = 0; i < testSize; i++){ -// gapsProjUsers[i][0] = recruitingProjs[i]; -// gapsProjUsers[i][1] = Math.abs(AccessDB.getTeamScore(Math.round(recruitingProjs[i])) - proficiency); -// System.out.println(i + ", projectId : " + Math.round(gapsProjUsers[i][0]) + ", |avgUrs - 숙련도| : " + gapsProjUsers[i][1]); -// } -// System.out.println("\n"); -// -// Arrays.sort(gapsProjUsers, Comparator.comparingDouble(arr -> arr[1])); -// -// for(i = 0; i < sampleSize; i++){ -// System.out.println("정렬됨 > " + i + ", projectId : " + Math.round(gapsProjUsers[i][0]) + ", |avgUrs - 숙련도| : " + gapsProjUsers[i][1]); -// } -// System.out.println("\n"); -// -// //------------------------------------------------------------------------------------------------------------------------------------- -// -// //구현 3: 이전 단계에서 구한 상위 sampleSize개의 샘플들에 대해서 모두 calculateUrs()를 이용해 urs를 구함 -// for(i = 0; i < sampleSize; i++){ -// selectedProjs[i][0] = gapsProjUsers[i][0]; -// selectedProjs[i][1] = AccessDB.getTeamScore(Math.round(gapsProjUsers[i][0])); -// selectedProjs[i][2] = proficiency + random.nextFloat() * 1.5f; //원래는 calculateUrs() 함수를 사용하여 urs를 구해야 하지만 DB 완성 전까지는 이와 같은 방식으로 대체 -// System.out.println(i + ", projectId : " + Math.round(selectedProjs[i][0]) + ", urs : " + selectedProjs[i][1]); -// } -// System.out.println("\n"); -// -// //구현 4: |selectedUsers[][2]-selectedUsers[][1]|의 값이 작은 순으로 recommendSize만큼 추출 ----------------------------------------- -// for(i = 0; i < sampleSize; i++){ -// selectedProjs[i][1] = Math.abs(selectedProjs[i][2]-selectedProjs[i][1]); -// } -// -// Arrays.sort(selectedProjs, Comparator.comparingDouble(arr -> arr[1])); -// -// for(i = 0; i < recommendSize; i++){ -// result[i] = Math.round(selectedProjs[i][0]); -// System.out.println("정렬됨 > " + i + ", projectId : " + Math.round(selectedProjs[i][0]) + ", |urs - avgUrs| : " + selectedProjs[i][1]); -// } -// System.out.println("\n"); -// //--------------------------------------------------------------------------------------------------------------------------------------------- -// -// return result; -// } -} + public static List userBaseSearch(int userId, String stack){ + ArrayList projIds=AccessDB.getAllProjectId(); + List projs=new ArrayList<>(); + + + for(Integer projId : projIds){ + List projectRequiredStack =AccessDB.getProjRequiredStack(projId); + for(String[] projStack : projectRequiredStack){ + //System.out.println(projStack[0]); + if(projStack[0].equals(stack)){ + //System.out.println(projStack[0]); + //System.out.println(projId); + //System.out.println(AccessDB.checkIsRecruiting(projId, stack)); + if(AccessDB.checkIsRecruiting(projId, stack)) { + float[] container=new float[2]; + container[0]=Float.valueOf(projId); + float score=AccessDB.getTeamScore(projId); + float urs=Urs.calculateUrs(projectRequiredStack,userId,stack); + container[1]= Math.abs(score-urs); + projs.add(container); + } + } + } + } + //projs 오름차순 정렬 후 + projs.sort(Comparator.comparingDouble(element -> element[1])); + + for (float[] row : projs) { + System.out.println(Arrays.toString(row)); + } + + + List userList = new ArrayList<>(); + + //개수에 따라 반환 10개 이상이면 10개로, 그 이하면 개수대로 int로 바꿔서 반환 + int limit = Math.min(10, projs.size()); + List result = projs.subList(0, limit); + + // element[0] 값을 int로 변환하여 List에 저장 + List intValues = new ArrayList<>(); + for (float[] element : result) { + intValues.add((int) element[0]); + } + + return intValues; + } + + public static List projectBaseSearch(int teamId, String stack){ + float teamScore=AccessDB.getTeamScore(teamId); + List projectRequiredStack =AccessDB.getProjRequiredStack(teamId); + + String dbStack=AccessDB.findStackForDB(stack); + + ArrayList intArray = AccessDB.getStackUserId(dbStack); + + // int[]를 float[][]로 변환 + float[][] scoreStorage = new float[intArray.size()][2]; + for (int i = 0; i < intArray.size(); i++) { + scoreStorage[i][0] = (float) intArray.get(i); // 명시적인 형 변환 + } + + int i=0; + for(Integer value : intArray){ + int userId=value; + float userUrs=Urs.calculateUrs(projectRequiredStack,userId,stack); + scoreStorage[i][1]= abs(userUrs-teamScore); + i++; + } + + // scoreStorage 배열을 scoreStorage[j][1]을 기준으로 오름차순 정렬 + Arrays.sort(scoreStorage, Comparator.comparingDouble(arr -> arr[1])); + + for (float[] row : scoreStorage) { + System.out.println(Arrays.toString(row)); + } + + List userList = new ArrayList<>(); + if(intArray.size()<10){ + for (int j = 0; j < intArray.size(); j++) { + userList.add((int) scoreStorage[j][0]); + } + }else{ + for (int j = 0; j < 10; j++) { + userList.add((int) scoreStorage[j][0]); + } + } + + return userList; + } +/* + public static void main(String[] args) { + float a = AccessDB.getTeamScore(3); + System.out.println("getTeamScore() test : " + a); + + List requiredStack = AccessDB.getProjRequiredStack(3); + + for (String[] dataArray : requiredStack) { + for (String data : dataArray) { + System.out.print(data + " "); + } + System.out.println(); // 각 배열마다 줄바꿈 + } + + String dbStack=AccessDB.findStackForDB("React"); + System.out.println(dbStack); + ArrayList intArray = AccessDB.getStackUserId(dbStack); + for (Integer value : intArray) { + System.out.print(value + " "); + } + System.out.println(); + + float c=Urs.calculateUrs(requiredStack,38,"React"); + System.out.println(c); + + List result= projectBaseSearch(3,"React"); + for (Integer value : result) { + System.out.print(value + " "); + } + System.out.println(); + + List intValue= userBaseSearch(38,"Java"); + for (Integer value : intValue) { + System.out.print(value + " "); + } + System.out.println(); + + } + + */ +} \ No newline at end of file diff --git a/Backend/src/main/java/com/example/demo/service/recommendCalc/Urs.java b/Backend/src/main/java/com/example/demo/service/recommendCalc/Urs.java index 577e56a..3a4c7c5 100644 --- a/Backend/src/main/java/com/example/demo/service/recommendCalc/Urs.java +++ b/Backend/src/main/java/com/example/demo/service/recommendCalc/Urs.java @@ -6,189 +6,63 @@ import java.util.List; public class Urs { + // 프로젝트의 평균 userRoleScore를 계산해주는 메소드 - static List stacks = Arrays.asList( - ".NET", "ASP.NET", "Angular", "AngularJS", "Apache Spark", "Blazor", "C", "C#", - "C++", "Dart", "Django", "Electron", "Express", "Flask", "Flutter", "Go", - "HTML/CSS", "Java", "JavaScript", "jQuery", "Keras", "Kotlin", "Laravel", "Lua", - "NestJS", "Next.js", "Node.js", "OpenGL", "Opencv", "PHP", "Pandas", "PyTorch", - "Python", "Qt", "R", "RabbitMQ", "React", "React Native", "Ruby", "Ruby on Rails", - "Rust", "scikit-Learn", "SpringBoot", "Svelte", "Swift", "SwiftUI", "TensorFlow", - "Torch", "TypeScript", "Vue.js" - ); + // 특정 프로젝트에서 특정 유저의 userRoleScore를 계산해주는 메소드 + static float calculateUrs(List projectRequiredStack, int userId, String targetStack){ + float urs = 0; + float distance=0; -// static float getTeamScore(int projId){ -// float avgScore = 0; -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT COUNT(*) AS data_count, SUM(user_role_score) AS score_sum " + -// "FROM project_member " + -// "WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// if (resultSet.next()) { -// float dataCount = resultSet.getFloat("data_count"); -// float scoreSum = resultSet.getFloat("score_sum"); -// -// System.out.println("데이터 개수: " + dataCount); -// System.out.println("user_role_score 합계: " + scoreSum); -// -// avgScore=scoreSum/dataCount; -// -// return avgScore; -// -// } else { -// System.out.println("일치하는 데이터가 없습니다."); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// return 0; -// } -// static List getUserAvailableStack(int userId){ -// String stacks_user=""; -// List requiredStack= new ArrayList<>(); -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM user WHERE id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, userId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_user = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// for(int i=0;i<50;i++){ -// if(stacks_user.length()==50){ -// if(stacks_user.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// } -// -// return requiredStack; -// } -// -// static List getProjRequiredStack(int projId){ -// String stacks_front=""; -// String stacks_back=""; -// String stacks_etc=""; -// List requiredStack= new ArrayList<>(); -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM project_front WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_front = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM project_back WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_back = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT stacks FROM project_etc WHERE project_id = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, projId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_etc = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// for(int i=0;i<50;i++){ -// if(stacks_front.length()==50){ -// if(stacks_front.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// -// if(stacks_back.length()==50){ -// if(stacks_back.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// -// if(stacks_etc.length()==50){ -// if(stacks_etc.charAt(i)=='8'){ -// requiredStack.add(stacks.get(i)); -// } -// } -// } -// -// return requiredStack; -// } -// -// static float getUserStackScore(int userId, String stack){ -// float stackscore=0; -// -// try (Connection connection = DriverManager.getConnection(jdbcUrl, DBusername, DBpassword)) { -// // 프로젝트 ID와 projId가 일치하는 데이터의 개수와 user_role_score의 합을 조회하는 SQL 쿼리 -// String sql = "SELECT score FROM "+ stack +" WHERE userId = ?"; -// -// try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { -// preparedStatement.setInt(1, userId); -// -// try (ResultSet resultSet = preparedStatement.executeQuery()) { -// while (resultSet.next()) { -// // stacks 값을 가져오기 -// stacks_front = resultSet.getString("stacks"); -// } -// } -// } -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// return stackscore; -// } -} + //구현: 유저(userId)가 사용할 줄 아는 기술스택 리스트를 USER_STACK 테이블에서 추출 ----------- + List userAvailableStack =AccessDB.getUserAvailableStack(userId); + + List intersection = new ArrayList<>(); + + // 교집합 찾기 + for (String[] required : projectRequiredStack) { + for (String[] available : userAvailableStack) { + if (Arrays.equals(required, available)) { + intersection.add(required); + break; + } + } + } +/* + System.out.println(projectRequiredStack.size()); + System.out.println(userAvailableStack.size()); + System.out.println(intersection.size()); + for (String[] element : intersection){ + System.out.println(element[0]); + System.out.println(element[1]); + } + + */ + + for(int i=0;i List findIntersection(List list1, List list2) { + List intersection = new ArrayList<>(); + + for (T element : list1) { + if (list2.contains(element)) { + intersection.add(element); + } + } + + return intersection; + } +} \ No newline at end of file