diff --git a/src/main/java/com/camillepradel/movierecommender/controller/MainController.java b/src/main/java/com/camillepradel/movierecommender/controller/MainController.java index a0b4d18..518981b 100644 --- a/src/main/java/com/camillepradel/movierecommender/controller/MainController.java +++ b/src/main/java/com/camillepradel/movierecommender/controller/MainController.java @@ -1,6 +1,5 @@ package com.camillepradel.movierecommender.controller; -import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -11,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.bind.annotation.RequestMethod; -import com.camillepradel.movierecommender.model.Genre; import com.camillepradel.movierecommender.model.Movie; import com.camillepradel.movierecommender.model.Rating; @@ -80,26 +78,16 @@ public class MainController { @RequestParam(value = "processing_mode", required = false, defaultValue = "0") Integer processingMode){ System.out.println("GET /movieratings for user " + userId); - // TODO: process recommendations for specified user exploiting other users ratings - // use different methods depending on processingMode parameter - Genre genre0 = new Genre(0, "genre0"); - Genre genre1 = new Genre(1, "genre1"); - Genre genre2 = new Genre(2, "genre2"); List recommendations = new LinkedList(); - String titlePrefix; - if (processingMode.equals(0)) - titlePrefix = "0_"; - else if (processingMode.equals(1)) - titlePrefix = "1_"; - else if (processingMode.equals(2)) - titlePrefix = "2_"; - else - titlePrefix = "default_"; - recommendations.add(new Rating(new Movie(0, titlePrefix + "Titre 0", Arrays.asList(new Genre[] {genre0, genre1})), userId, 5)); - recommendations.add(new Rating(new Movie(1, titlePrefix + "Titre 1", Arrays.asList(new Genre[] {genre0, genre2})), userId, 5)); - recommendations.add(new Rating(new Movie(2, titlePrefix + "Titre 2", Arrays.asList(new Genre[] {genre1})), userId, 4)); - recommendations.add(new Rating(new Movie(3, titlePrefix + "Titre 3", Arrays.asList(new Genre[] {genre0, genre1, genre2})), userId, 3)); + if (processingMode.equals(1)){ + recommendations = Neo4JController.ProcessRecommendationV1(userId); + } + else if (processingMode.equals(2)){ + recommendations = Neo4JController.ProcessRecommendationV2(userId); + + } + ModelAndView mv = new ModelAndView("recommendations"); mv.addObject("recommendations", recommendations); diff --git a/src/main/java/com/camillepradel/movierecommender/controller/Neo4JController.java b/src/main/java/com/camillepradel/movierecommender/controller/Neo4JController.java index 91345bd..3636204 100644 --- a/src/main/java/com/camillepradel/movierecommender/controller/Neo4JController.java +++ b/src/main/java/com/camillepradel/movierecommender/controller/Neo4JController.java @@ -21,113 +21,177 @@ import org.neo4j.driver.v1.StatementResult; * @author renando */ public class Neo4JController { - - public static ListgetMoviesNeo4JByUser (Integer userId){ - List movies = new LinkedList(); - int id=0; - StatementResult result = null; - try { - if (userId != null && userId >=0 ){ - - result = Neo4jConnector.getInstance().getConnection().run( "MATCH (me:User { id: "+userId+" })-[:RATED]->(movie:Movie) -[:CATEGORIZED_AS]->(g:Genre) RETURN movie.title as movies, collect(g.name) as genre;" ); - } - else{ - result = Neo4jConnector.getInstance().getConnection().run( "MATCH (m:Movie) -[:CATEGORIZED_AS]->(g:Genre) RETURN m.title as movies, collect(g.name) as genre;" ); - } - } catch (ConnectException ex) { - Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex); - } - finally{ - Neo4jConnector.getInstance().close(); - } - while ( result.hasNext() ) - { - Record record = result.next(); - String[] listGenre = record.get("genre").toString().split(","); - List listTypeGenre = new LinkedList(); - for(String g : listGenre){ - if(g != null) - listTypeGenre.add(new Genre(id, g.replace("\"", "").replace("[", "").replace("]", ""))); - - } - movies.add(new Movie(id, record.get("movies").asString(), (listTypeGenre.isEmpty())?null:listTypeGenre ) ); - id+=1; - } - return movies; - } - - - public static ListGetMoviesRatingNeo4JByUser(Integer userId){ - List moviesRating = new LinkedList(); - StatementResult result = null; - try { - if (userId != null && userId >=0 ){ - - result = Neo4jConnector.getInstance().getConnection().run( "MATCH (u:User{id:"+userId+"})-[r:RATED]->(m:Movie)-[:CATEGORIZED_AS]->(g:Genre) RETURN m.id AS id, m.title AS title, collect(g.name) AS genre, r.note AS note ORDER BY id" ); + public static List getMoviesNeo4JByUser(Integer userId) { + List movies = new LinkedList(); + int id = 0; + StatementResult result = null; + try { + if (userId != null && userId >= 0) { + + result = Neo4jConnector.getInstance().getConnection().run("MATCH (me:User { id: " + userId + " })-[:RATED]->(movie:Movie) -[:CATEGORIZED_AS]->(g:Genre) RETURN movie.title as movies, collect(g.name) as genre;"); + } else { + result = Neo4jConnector.getInstance().getConnection().run("MATCH (m:Movie) -[:CATEGORIZED_AS]->(g:Genre) RETURN m.title as movies, collect(g.name) as genre;"); } - else{ + } catch (ConnectException ex) { + Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex); + } finally { + Neo4jConnector.getInstance().close(); + } + while (result.hasNext()) { + Record record = result.next(); + String[] listGenre = record.get("genre").toString().split(","); + List listTypeGenre = new LinkedList(); + for (String g : listGenre) { + if (g != null) { + listTypeGenre.add(new Genre(id, g.replace("\"", "").replace("[", "").replace("]", ""))); + } + + } + movies.add(new Movie(id, record.get("movies").asString(), (listTypeGenre.isEmpty()) ? null : listTypeGenre)); + id += 1; + } + return movies; + } + + public static List GetMoviesRatingNeo4JByUser(Integer userId) { + List moviesRating = new LinkedList(); + + StatementResult result = null; + try { + if (userId != null && userId >= 0) { + + result = Neo4jConnector.getInstance().getConnection().run("MATCH (u:User{id:" + userId + "})-[r:RATED]->(m:Movie)-[:CATEGORIZED_AS]->(g:Genre) RETURN m.id AS id, m.title AS title, collect(g.name) AS genre, r.note AS note ORDER BY id"); + } else { return null; } - } catch (ConnectException ex) { - Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex); - } - finally{ - Neo4jConnector.getInstance().close(); - } - Movie movie = null; - Rating rate = null; - - while ( result.hasNext() ) - { - Record record = result.next(); - System.out.println(record.get("p").toString()); - String[] listGenre = record.get("genre").toString().split(","); - List listTypeGenre = new LinkedList(); - for(String g : listGenre){ - if(g != null) - listTypeGenre.add(new Genre(0, g.replace("\"", "").replace("[", "").replace("]", ""))); - + } catch (ConnectException ex) { + Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex); + } finally { + Neo4jConnector.getInstance().close(); + } + Movie movie = null; + Rating rate = null; + + while (result.hasNext()) { + Record record = result.next(); + System.out.println(record.get("p").toString()); + String[] listGenre = record.get("genre").toString().split(","); + List listTypeGenre = new LinkedList(); + for (String g : listGenre) { + if (g != null) { + listTypeGenre.add(new Genre(0, g.replace("\"", "").replace("[", "").replace("]", ""))); } - movie = new Movie(record.get("id").asInt(), record.get("title").asString(),listTypeGenre ); - rate = new Rating(movie, userId, record.get("note").asInt()); - moviesRating.add(rate); + } - return moviesRating; - + movie = new Movie(record.get("id").asInt(), record.get("title").asString(), listTypeGenre); + rate = new Rating(movie, userId, record.get("note").asInt()); + moviesRating.add(rate); } - - public static void updateMovieRatingNeo4J(Rating note){ + return moviesRating; - Integer user_id = note.getUserId(); - try { - if (user_id != null && user_id >=0 ){ - - Neo4jConnector.getInstance().getConnection().run( "MATCH (u:User{id:"+user_id+"})-[r:RATED]->(m:Movie)\n" + - "where m.id ="+note.getMovie().getId()+"\n" + - "delete r" ); + } + + public static void updateMovieRatingNeo4J(Rating note) { + + Integer user_id = note.getUserId(); + try { + if (user_id != null && user_id >= 0) { + + Neo4jConnector.getInstance().getConnection().run("MATCH (u:User{id:" + user_id + "})-[r:RATED]->(m:Movie)\n" + + "where m.id =" + note.getMovie().getId() + "\n" + + "delete r"); } - } catch (ConnectException ex) { - System.out.println(ex); - } - finally{ - Neo4jConnector.getInstance().close(); - } - - - try { - Neo4jConnector.getInstance().getConnection().run( "MATCH (u:User{id:"+user_id+"}),(m:Movie)\n" + - "where m.id = "+note.getMovie().getId()+"\n" + - "CREATE (u)-[r:RATED{note:"+note.getScore()+", timestamp: "+System.currentTimeMillis()+"}]->(m) \n" + - "RETURN *" ); - - } catch (ConnectException ex) { - System.out.println(ex); - } - finally{ - Neo4jConnector.getInstance().close(); - } + } catch (ConnectException ex) { + System.out.println(ex); + } finally { + Neo4jConnector.getInstance().close(); } - + + try { + Neo4jConnector.getInstance().getConnection().run("MATCH (u:User{id:" + user_id + "}),(m:Movie)\n" + + "where m.id = " + note.getMovie().getId() + "\n" + + "CREATE (u)-[r:RATED{note:" + note.getScore() + ", timestamp: " + System.currentTimeMillis() + "}]->(m) \n" + + "RETURN *"); + + } catch (ConnectException ex) { + System.out.println(ex); + } finally { + Neo4jConnector.getInstance().close(); + } + } + + public static List ProcessRecommendationV1(Integer userId) { + + List ratings = new LinkedList(); + StatementResult result = null; + + try { + result = Neo4jConnector.getInstance().getConnection().run("MATCH (target_user:User {id : " + userId + "})-[:RATED]->(m:Movie)<-[:RATED]-(other_user:User)\n" + + "WITH other_user, count(distinct m.title) AS num_common_movies, target_user\n" + + "ORDER BY num_common_movies DESC\n" + + "LIMIT 1\n" + + "MATCH (other_user)-[rat_other_user:RATED]->(m2:Movie)\n" + + "WHERE NOT ((target_user)-[:RATED]->(m2))\n" + + "RETURN m2.id AS mov_id, m2.title AS rec_movie_title, rat_other_user.note AS rating, other_user.id AS watched_by\n" + + "ORDER BY rat_other_user.note DESC"); + } catch (ConnectException ex) { + Logger.getLogger(Neo4JController.class.getName()).log(Level.SEVERE, null, ex); + } finally { + Neo4jConnector.getInstance().close(); + } + Record record = null; + int idMovie = 0; + String titre = ""; + int note = 0; + while (result.hasNext()) { + record = result.next(); + idMovie = record.get("mov_id").asInt(); + titre = record.get("rec_movie_title").asString(); + note = record.get("rating").asInt(); + System.out.println(titre); + ratings.add(new Rating(new Movie(idMovie, titre,null), userId, note)); + } + return ratings; + + } + + public static List ProcessRecommendationV2(Integer userId) { + + List ratings = new LinkedList(); + StatementResult result = null; + + try { + + result = Neo4jConnector.getInstance().getConnection().run("MATCH (target_user:User {id : " + userId + "})-[:RATED]->(m:Movie)<-[:RATED]-(other_user:User)\n" + + "WITH other_user, count(distinct m.title) AS num_common_movies, target_user\n" + + "ORDER BY num_common_movies DESC\n" + + "LIMIT 5\n" + + "MATCH (other_user)-[rat_other_user:RATED]->(m2:Movie)\n" + + "WHERE NOT ((target_user)-[:RATED]->(m2))\n" + + "RETURN m2.id AS mov_id, m2.title AS rec_movie_title, rat_other_user.note AS rating, other_user.id AS watched_by\n" + + "ORDER BY rat_other_user.note DESC"); + + } catch (ConnectException ex) { + Logger.getLogger(Neo4JController.class.getName()).log(Level.SEVERE, null, ex); + } finally { + Neo4jConnector.getInstance().close(); + } + Record record = null; + int idMovie = 0; + String titre = ""; + int note = 0; + while (result.hasNext()) { + record = result.next(); + idMovie = record.get("mov_id").asInt(); + titre = record.get("rec_movie_title").asString(); + note = record.get("rating").asInt(); + + ratings.add(new Rating(new Movie(idMovie, titre,null), userId, note)); + } + return ratings; + + } + } diff --git a/src/main/webapp/WEB-INF/views/recommendations.jsp b/src/main/webapp/WEB-INF/views/recommendations.jsp index 0d93e2e..3ea1e99 100644 --- a/src/main/webapp/WEB-INF/views/recommendations.jsp +++ b/src/main/webapp/WEB-INF/views/recommendations.jsp @@ -12,11 +12,9 @@ Vos recommandations
    - -
  • - ${recommendation.getMovie().title} -
  • -
    + +
  • ${recommendation.movie.title} - ${recommendation.score} / 5
  • +