added non-aj cineasts example

renamed all cineasts examples in pom.xml
This commit is contained in:
Michael Hunger
2011-11-05 09:29:26 +01:00
parent 6a8c6e4776
commit d453ccd084
20 changed files with 221 additions and 271 deletions

View File

@@ -3,11 +3,11 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.neo4j.examples</groupId>
<artifactId>movies-aspects</artifactId>
<artifactId>cineasts-aspects</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Movies</name>
<name>Cineasts.net Aspects</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@@ -3,11 +3,11 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.neo4j</groupId>
<artifactId>movies-rest</artifactId>
<artifactId>cineasts-rest</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Movies over REST</name>
<name>Cineasts over REST</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@@ -0,0 +1,12 @@
.DS_Store
*.ipr
*.iws
*.iml
*.zip
data
target
*.log
tmp
.classpath
.project
.settings

View File

@@ -7,7 +7,7 @@
<version>2.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Movies</name>
<name>Cineasts.net</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -16,7 +16,6 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<neo4j.version>1.5.M02</neo4j.version>
<spring-data-graph.version>2.0.0.BUILD-SNAPSHOT</spring-data-graph.version>
<aspectj.version>1.6.12.M1</aspectj.version>
<org.slf4j-version>1.6.1</org.slf4j-version>
</properties>
@@ -176,7 +175,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-aspects</artifactId>
<artifactId>spring-data-neo4j</artifactId>
<version>${spring-data-graph.version}</version>
<exclusions>
<exclusion>
@@ -222,11 +221,11 @@
<version>1.7.2</version>
</dependency>
<dependency>
<!--dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependency-->
<dependency>
<groupId>cglib</groupId>
@@ -234,12 +233,6 @@
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<!-- Neo4j Libraries -->
<dependency>
@@ -318,7 +311,7 @@
</configuration>
</plugin>
<plugin>
<!--plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version>
@@ -357,7 +350,7 @@
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugin-->
</plugins>
</build>

View File

@@ -6,7 +6,7 @@ import org.neo4j.cineasts.domain.Rating;
import org.neo4j.cineasts.domain.User;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.cineasts.repository.PersonRepository;
import org.neo4j.cineasts.service.CineastsRepository;
import org.neo4j.cineasts.repository.UserRepository;
import org.neo4j.cineasts.service.CineastsUserDetailsService;
import org.neo4j.cineasts.service.DatabasePopulator;
import org.neo4j.helpers.collection.IteratorUtil;
@@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.neo4j.template.Neo4jOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@@ -34,8 +35,12 @@ public class MovieController {
@Autowired
private PersonRepository personRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private CineastsUserDetailsService userDetailsService;
@Autowired
Neo4jOperations template;
@Autowired
private DatabasePopulator populator;
private static final Logger log = LoggerFactory.getLogger(MovieController.class);
@@ -61,7 +66,7 @@ public class MovieController {
final int stars = movie.getStars();
model.addAttribute("stars", stars);
Rating rating = null;
if (user!=null) rating = movie.getRelationshipTo(user, Rating.class, "RATED");
if (user!=null) rating = template.getRelationshipBetween(movie, user, Rating.class, "RATED");
if (rating == null) rating = new Rating().rate(stars,null);
model.addAttribute("userRating",rating);
}
@@ -75,7 +80,7 @@ public class MovieController {
if (user != null && movie != null) {
int stars1 = stars==null ? -1 : stars;
String comment1 = comment!=null ? comment.trim() : null;
user.rate(movie, stars1, comment1);
user.rate(template,movie, stars1, comment1);
}
return singleMovieView(model,movieId);
}

View File

@@ -1,11 +1,7 @@
package org.neo4j.cineasts.domain;
import org.neo4j.graphdb.Direction;
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.support.index.IndexType;
import java.util.*;
@@ -19,6 +15,7 @@ import static org.neo4j.graphdb.Direction.INCOMING;
*/
@NodeEntity
public class Movie {
@GraphId Long nodeId;
@Indexed
String id;
@@ -34,11 +31,11 @@ public class Movie {
@RelatedTo(type = "ACTS_IN", direction = INCOMING)
Set<Person> actors;
@RelatedToVia(elementClass = Role.class, type = "ACTS_IN", direction = INCOMING)
@RelatedToVia(type = "ACTS_IN", direction = INCOMING)
Iterable<Role> roles;
@RelatedToVia(elementClass = Rating.class, type = "RATED", direction = INCOMING)
Iterable<Rating> ratings;
@RelatedToVia(type = "RATED", direction = INCOMING)
@Fetch Iterable<Rating> ratings;
private String language;
private String imdbId;
private String tagline;
@@ -224,5 +221,22 @@ public class Movie {
int numberOfParts = parts.length;
return numberOfParts > 0 ? parts[numberOfParts-1] : null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Movie movie = (Movie) o;
if (nodeId == null) return super.equals(o);
return nodeId.equals(movie.nodeId);
}
@Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
}

View File

@@ -1,12 +1,11 @@
package org.neo4j.cineasts.domain;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.support.index.IndexType;
import org.springframework.data.neo4j.template.Neo4jOperations;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
/**
@@ -15,6 +14,7 @@ import java.util.Set;
*/
@NodeEntity
public class Person {
@GraphId Long nodeId;
@Indexed
String id;
@Indexed(indexType=IndexType.FULLTEXT, indexName = "people")
@@ -100,7 +100,7 @@ public class Person {
}
@RelatedTo(elementClass = Movie.class, type = "DIRECTED")
private Set<Movie> directedMovies;
private Set<Movie> directedMovies=new HashSet<Movie>();
public Set<Movie> getDirectedMovies() {
return directedMovies;
@@ -117,10 +117,27 @@ public class Person {
return roles;
}
public Role playedIn(Movie movie, String roleName) {
Role role = relateTo(movie, Role.class, "ACTS_IN");
public Role playedIn(Neo4jOperations template,Movie movie, String roleName) {
Role role = template.createRelationshipBetween(this, movie, Role.class, "ACTS_IN",false);
role.setName(roleName);
return role;
return template.save(role);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (nodeId == null) return super.equals(o);
return nodeId.equals(person.nodeId);
}
@Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
}

View File

@@ -1,8 +1,6 @@
package org.neo4j.cineasts.domain;
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
import org.springframework.data.neo4j.annotation.*;
/**
* @author mh
@@ -12,9 +10,9 @@ import org.springframework.data.neo4j.annotation.StartNode;
public class Rating {
private static final int MAX_STARS = 5;
private static final int MIN_STARS = 0;
@GraphId Long id;
@StartNode
User user;
@StartNode User user;
@EndNode Movie movie;
int stars;
@@ -49,4 +47,21 @@ public class Rating {
if (comment!=null && !comment.isEmpty()) this.comment = comment;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Rating rating = (Rating) o;
if (id == null) return super.equals(o);
return id.equals(rating.id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}

View File

@@ -1,6 +1,7 @@
package org.neo4j.cineasts.domain;
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
@@ -10,6 +11,7 @@ import org.springframework.data.neo4j.annotation.StartNode;
*/
@RelationshipEntity
public class Role {
@GraphId Long id;
@EndNode Movie movie;
@StartNode Person actor;
@@ -35,4 +37,21 @@ public class Role {
public String toString() {
return String.format("%s acts as %s in %s", actor, name, movie);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Role role = (Role) o;
if (id == null) return super.equals(o);
return id.equals(role.id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}

View File

@@ -2,10 +2,8 @@ package org.neo4j.cineasts.domain;
import org.neo4j.graphdb.Direction;
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.template.Neo4jOperations;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.GrantedAuthority;
@@ -14,6 +12,8 @@ import java.util.Set;
@NodeEntity
public class User {
@GraphId Long nodeId;
private static final String SALT = "cewuiqwzie";
public static final String FRIEND = "FRIEND";
public static final String RATED = "RATED";
@@ -38,22 +38,23 @@ public class User {
return new Md5PasswordEncoder().encodePassword(password, SALT);
}
@RelatedToVia(elementClass = Rating.class, type = RATED)
Iterable<Rating> ratings;
@RelatedToVia(type = RATED)
@Fetch Iterable<Rating> ratings;
@RelatedTo(elementClass = Movie.class, type = RATED)
@RelatedTo(type = RATED)
Set<Movie> favorites;
@RelatedTo(elementClass = User.class, type = FRIEND, direction = Direction.BOTH)
Set<User> friends;
@RelatedTo(type = FRIEND, direction = Direction.BOTH)
@Fetch Set<User> friends;
public void addFriend(User friend) {
this.friends.add(friend);
}
public Rating rate(Movie movie, int stars, String comment) {
return relateTo(movie, Rating.class, RATED).rate(stars, comment);
public Rating rate(Neo4jOperations template, Movie movie, int stars, String comment) {
final Rating rating = template.createRelationshipBetween(this, movie, Rating.class, RATED, false).rate(stars, comment);
return template.save(rating);
}
public Collection<Rating> getRatings() {
@@ -114,4 +115,20 @@ public class User {
return name();
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (nodeId == null) return super.equals(o);
return nodeId.equals(user.nodeId);
}
@Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
}

View File

@@ -1,12 +1,14 @@
package org.neo4j.cineasts.movieimport;
import org.neo4j.cineasts.domain.*;
import org.neo4j.cineasts.domain.Movie;
import org.neo4j.cineasts.domain.Person;
import org.neo4j.cineasts.domain.Roles;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.cineasts.repository.PersonRepository;
import org.neo4j.cineasts.service.CineastsRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.template.Neo4jOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -21,15 +23,16 @@ public class MovieDbImportService {
MovieDbJsonMapper movieDbJsonMapper = new MovieDbJsonMapper();
@Autowired
MovieRepository movieRepository;
private MovieRepository movieRepository;
@Autowired
PersonRepository personRepository;
private PersonRepository personRepository;
@Autowired
MovieDbApiClient client;
private MovieDbApiClient client;
@Autowired
MovieDbLocalStorage localStorage;
private MovieDbLocalStorage localStorage;
@Autowired private Neo4jOperations template;
@Transactional
public Map<Integer, String> importMovies(Map<Integer, Integer> ranges) {
@@ -68,7 +71,7 @@ public class MovieDbImportService {
Map data = loadMovieData(movieId);
if (data.containsKey("not_found")) throw new RuntimeException("Data for Movie "+movieId+" not found.");
movieDbJsonMapper.mapToMovie(data, movie);
movie.persist();
movieRepository.save(movie);
relatePersonsToMovie(movie, data);
return movie;
}
@@ -84,7 +87,7 @@ public class MovieDbImportService {
}
private void relatePersonsToMovie(Movie movie, Map data) {
Collection<Map> cast = (Collection<Map>) data.get("cast");
@SuppressWarnings("unchecked") Collection<Map> cast = (Collection<Map>) data.get("cast");
for (Map entry : cast) {
String id = "" + entry.get("id");
String jobName = (String) entry.get("job");
@@ -99,7 +102,7 @@ public class MovieDbImportService {
person.directed(movie);
break;
case ACTS_IN:
person.playedIn(movie, (String) entry.get("character"));
person.playedIn(template,movie, (String) entry.get("character"));
break;
}
}
@@ -118,7 +121,7 @@ public class MovieDbImportService {
if (data.containsKey("not_found")) throw new RuntimeException("Data for Person "+personId+" not found.");
Person newPerson=new Person(personId,null);
movieDbJsonMapper.mapToPerson(data, newPerson);
return newPerson.persist();
return personRepository.save(newPerson);
}
private Map loadPersonData(String personId) {

View File

@@ -8,6 +8,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.NamedIndexRepository;
import org.springframework.data.neo4j.repository.RelationshipOperationsRepository;
import java.util.List;
@@ -15,7 +16,7 @@ import java.util.List;
* @author mh
* @since 02.04.11
*/
public interface MovieRepository extends GraphRepository<Movie>, NamedIndexRepository<Movie> {
public interface MovieRepository extends GraphRepository<Movie>, NamedIndexRepository<Movie>, RelationshipOperationsRepository<Movie> {
Movie findById(String id);
Page<Movie> findByTitleLike(String title, Pageable page);

View File

@@ -2,11 +2,12 @@ package org.neo4j.cineasts.repository;
import org.neo4j.cineasts.domain.Person;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.RelationshipOperationsRepository;
/**
* @author mh
* @since 02.04.11
*/
public interface PersonRepository extends GraphRepository<Person> {
public interface PersonRepository extends GraphRepository<Person>, RelationshipOperationsRepository<Person> {
Person findById(String id);
}

View File

@@ -2,10 +2,11 @@ package org.neo4j.cineasts.repository;
import org.neo4j.cineasts.domain.User;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.RelationshipOperationsRepository;
/**
* @author mh
* @since 02.04.11
*/
public interface UserRepository extends GraphRepository<User> {
public interface UserRepository extends GraphRepository<User>, RelationshipOperationsRepository<User> {
}

View File

@@ -1,13 +1,14 @@
package org.neo4j.cineasts.service;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.kernel.AbstractGraphDatabase;
import org.neo4j.cineasts.domain.*;
import org.neo4j.cineasts.domain.Movie;
import org.neo4j.cineasts.domain.User;
import org.neo4j.cineasts.movieimport.MovieDbImportService;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.cineasts.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.template.Neo4jOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -23,10 +24,9 @@ import static java.util.Arrays.asList;
@Service
public class DatabasePopulator {
@Autowired
Neo4jTemplate ctx;
@Autowired
MovieRepository movieRepository;
@Autowired UserRepository userRepository;
@Autowired MovieRepository movieRepository;
@Autowired Neo4jOperations template;
@Autowired
MovieDbImportService importService;
@@ -34,8 +34,8 @@ public class DatabasePopulator {
@Transactional
public List<Movie> populateDatabase() {
User me = new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER).persist();
User ollie = new User("ollie", "Olliver", "password",User.Roles.ROLE_USER).persist();
User me = userRepository.save(new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER));
User ollie = userRepository.save(new User("ollie", "Olliver", "password",User.Roles.ROLE_USER));
me.addFriend(ollie);
List<Integer> ids = asList(19995 , 194, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 13, 20526, 11, 1893, 1892, 1894, 168, 193, 200, 157, 152, 201, 154, 12155, 58, 285, 118, 22, 392, 5255, 568, 9800, 497, 101, 120, 121, 122);
List<Movie> result=new ArrayList<Movie>(ids.size());
@@ -44,12 +44,13 @@ public class DatabasePopulator {
}
//me.rate(repository.getMovie("13"),5,"Inspiring");
me.rate(movieRepository.findById("603"),5,"Best of the series");
final Movie movie = movieRepository.findById("603");
me.rate(template, movie,5,"Best of the series");
return result;
}
@Transactional
public void cleanDb() {
new Neo4jDatabaseCleaner((AbstractGraphDatabase) ctx.getGraphDatabaseService()).cleanDb();
new Neo4jDatabaseCleaner(template).cleanDb();
}
}

View File

@@ -1,74 +0,0 @@
package org.neo4j.cineasts.service;
import org.neo4j.cineasts.domain.Movie;
import org.neo4j.cineasts.domain.Rating;
import org.neo4j.cineasts.domain.User;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.Traversal;
import org.neo4j.kernel.Uniqueness;
import org.springframework.data.neo4j.core.EntityPath;
import java.util.HashMap;
import java.util.Map;
import static org.neo4j.graphdb.DynamicRelationshipType.withName;
/**
* @author mh
* @since 04.04.11
*/
public class FriendsMovieRecommendations {
private final Map<Movie, MovieRating> ratings = new HashMap<Movie, MovieRating>();
private final int ratingDistance;
public static class MovieRating {
int stars;
int count;
public void update(Rating rating, int weight) {
this.stars += rating.getStars()*weight;
this.count += weight;
}
public int average() {
return count == 0 ? 0 : stars / count;
}
public String toString() {
return String.valueOf(average());
}
}
public FriendsMovieRecommendations(int ratingDistance) {
this.ratingDistance = ratingDistance;
}
public Map<Movie, ?> getRecommendationsFor(User user) {
TraversalDescription traversal = Traversal.description().breadthFirst()
.uniqueness(Uniqueness.NODE_GLOBAL).relationships(withName(User.FRIEND))
.evaluator(Evaluators.toDepth(ratingDistance)).evaluator(Evaluators.excludeStartPosition());
Iterable result = user.findAllPathsByTraversal(traversal);
Iterable<EntityPath<User,User>> friends = (Iterable<EntityPath<User,User>>)result;
for (EntityPath<User,User> path : friends) {
int weight = ratingDistance - path.length();
User friend = path.endEntity();
aggregateRatings(friend,weight);
}
for (Rating rating : user.getRatings()) {
ratings.remove(rating.getMovie());
}
return ratings;
}
private void aggregateRatings(User friend, int weight) {
for (Rating rating : friend.getRatings()) {
obtainRating(rating.getMovie()).update(rating, weight);
}
}
private MovieRating obtainRating(Movie movie) {
if (!ratings.containsKey(movie)) {
ratings.put(movie, new MovieRating());
}
return ratings.get(movie);
}
}

View File

@@ -1,82 +0,0 @@
package org.neo4j.cineasts.service;
import org.neo4j.cineasts.domain.Movie;
import org.neo4j.cineasts.domain.User;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.Traversal;
import org.neo4j.kernel.Uniqueness;
import java.util.HashMap;
import java.util.Map;
import static org.neo4j.graphdb.Direction.OUTGOING;
import static org.neo4j.graphdb.DynamicRelationshipType.withName;
/**
* @author mh
* @since 04.04.11
*/
class MovieRecommendations implements Evaluator {
private final Map<Long,int[]> ratings=new HashMap<Long, int[]>();
private final int ratingDistance;
private MovieRepository movieRepository;
public MovieRecommendations(MovieRepository movieRepository, int ratingDistance) {
this.movieRepository = movieRepository;
this.ratingDistance = ratingDistance;
}
public Map<Movie, ?> getRecommendationsFor(User user) {
TraversalDescription traversal= Traversal.description().breadthFirst()
.uniqueness(Uniqueness.NODE_PATH)
.relationships(withName(User.FRIEND))
.relationships(withName(User.RATED), OUTGOING)
.evaluator(this);
return averageRecommendations(user, traversal);
}
private Map<Movie, Integer> averageRecommendations(User user, TraversalDescription traversal) { // todo sort, limit
Map<Movie,Integer> result=new HashMap<Movie, Integer>();
for (Movie movie : movieRepository.findAllByTraversal(user, traversal)) {
final int[] rating = ratings.get(movie.getNodeId());
result.put(movie, rating[1]==0 ? 0 : rating[0]/rating[1]);
}
return result;
}
@Override
public Evaluation evaluate(Path path) {
final int distance = path.length() - 1;
if (distance > ratingDistance) return Evaluation.EXCLUDE_AND_PRUNE;
Relationship rated = path.lastRelationship();
if (rated != null && rated.getType().name().equals(User.RATED)) {
if (distance == 0) return Evaluation.EXCLUDE_AND_PRUNE; // my rated movies
updateRating(rated, distance);
return Evaluation.INCLUDE_AND_PRUNE;
}
System.out.println();
return Evaluation.EXCLUDE_AND_CONTINUE;
}
private void updateRating(Relationship rated, int distance) {
final long movieId = rated.getEndNode().getId();
int[] rating = obtainRating(movieId);
int weight = ratingDistance - distance;
final Integer stars = (Integer) rated.getProperty("stars", 0);
rating[0] += weight * stars;
rating[1] += weight;
}
private int[] obtainRating(long movieId) {
if (!ratings.containsKey(movieId)) {
ratings.put(movieId,new int[2]);
}
return ratings.get(movieId);
}
}

View File

@@ -1,11 +1,9 @@
package org.neo4j.cineasts.service;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.kernel.AbstractGraphDatabase;
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
import org.springframework.data.neo4j.template.Neo4jOperations;
import java.util.Arrays;
import java.util.HashMap;
@@ -16,10 +14,10 @@ import java.util.Map;
* @since 02.03.11
*/
public class Neo4jDatabaseCleaner {
private AbstractGraphDatabase graph;
private GraphDatabaseService graph;
public Neo4jDatabaseCleaner(AbstractGraphDatabase graph) {
this.graph = graph;
public Neo4jDatabaseCleaner(Neo4jOperations template) {
this.graph = ((DelegatingGraphDatabase)template.getGraphDatabase()).getGraphDatabaseService();
}
public Map<String, Object> cleanDb() {

View File

@@ -4,8 +4,10 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.cineasts.repository.PersonRepository;
import org.neo4j.cineasts.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.template.Neo4jOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@@ -30,18 +32,21 @@ public class DomainTest {
@Autowired
protected UserRepository userRepository;
@Autowired Neo4jOperations template;
@Autowired PersonRepository personRepository;
@Before
public void setUp() throws Exception {
}
@Test
public void actorCanPlayARoleInAMovie() {
Person tomHanks = new Person("1","Tom Hanks").persist();
Movie forestGump = new Movie("1", "Forrest Gump").persist();
Person tomHanks = template.save(new Person("1", "Tom Hanks"));
Movie forestGump = template.save(new Movie("1", "Forrest Gump"));
Role role = tomHanks.playedIn(forestGump, "Forrest");
Role role = tomHanks.playedIn(template, forestGump, "Forrest");
Movie foundForestGump = this.movieRepository.findByPropertyValue(null, "id", "1");
Movie foundForestGump = this.movieRepository.findById("1");
assertEquals("created and looked up movie equal", forestGump, foundForestGump);
Role firstRole = foundForestGump.getRoles().iterator().next();
@@ -51,7 +56,7 @@ public class DomainTest {
@Test
public void canFindMovieByTitleQuery() {
Movie forestGump = new Movie("1", "Forrest Gump").persist();
Movie forestGump = template.save(new Movie("1", "Forrest Gump"));
Iterator<Movie> queryResults = movieRepository.findAllByQuery("search", "title", "Forre*").iterator();
assertTrue("found movie by query",queryResults.hasNext());
Movie foundMovie = queryResults.next();
@@ -61,12 +66,12 @@ public class DomainTest {
@Test
public void userCanRateMovie() {
Movie movie= new Movie("1","Forrest Gump").persist();
User user = new User("ich","Micha","password").persist();
Rating awesome = user.rate(movie, 5, "Awesome");
Movie movie = template.save(new Movie("1", "Forrest Gump"));
User user = template.save(new User("ich", "Micha", "password"));
Rating awesome = user.rate(template, movie, 5, "Awesome");
User foundUser = userRepository.findByPropertyValue("login", "ich");
user = userRepository.findByPropertyValue("login", "ich");
movie = movieRepository.findById("1");
Rating rating = user.getRatings().iterator().next();
assertEquals(awesome,rating);
assertEquals("Awesome",rating.getComment());
@@ -75,7 +80,7 @@ public class DomainTest {
}
@Test
public void canFindUserByLogin() {
User user = new User("ich","Micha","password").persist();
User user = template.save(new User("ich", "Micha", "password"));
User foundUser = userRepository.findByPropertyValue("login", "ich");
assertEquals(user, foundUser);
}

View File

@@ -7,9 +7,11 @@ import org.neo4j.cineasts.domain.MovieRecommendation;
import org.neo4j.cineasts.domain.Rating;
import org.neo4j.cineasts.domain.User;
import org.neo4j.cineasts.repository.MovieRepository;
import org.neo4j.cineasts.repository.UserRepository;
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.neo4j.template.Neo4jOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@@ -29,25 +31,26 @@ import static org.junit.Assert.assertTrue;
@ContextConfiguration({"/movies-test-context.xml"})
@Transactional
public class MoviesRepositoryTest {
@Autowired
MovieRepository movieRepository;
@Autowired MovieRepository movieRepository;
@Autowired UserRepository userRepository;
@Autowired Neo4jOperations template;
@Test
public void testGetMovie() throws Exception {
Movie movie = new Movie("1", "Test-Movie").persist();
Movie movie = movieRepository.save(new Movie("1", "Test-Movie"));
Movie found = movieRepository.findById("1");
assertEquals("movie found by id", movie, found);
}
@Test
public void testGetMovieRecommendations() throws Exception {
Movie movie = new Movie("1", "Test-Movie").persist();
Movie movie2 = new Movie("2", "Test-Movie2").persist();
User user=new User("me","me","me").persist();
user.rate(movie,3,"me");
User friend=new User("friend","friend","friend").persist();
friend.rate(movie,5,"friend");
friend.rate(movie2,3,"friend2");
Movie movie = movieRepository.save(new Movie("1", "Test-Movie"));
Movie movie2 = movieRepository.save(new Movie("2", "Test-Movie2"));
User user = userRepository.save(new User("me", "me", "me"));
user.rate(template,movie,3,"me");
User friend = userRepository.save(new User("friend", "friend", "friend"));
friend.rate(template, movie, 5, "friend");
friend.rate(template, movie2, 3, "friend2");
assertEquals(2,movieRepository.count());
final List<MovieRecommendation> recommendations = movieRepository.getRecommendations(user);
assertEquals("one recommendation", 1, recommendations.size());
@@ -56,9 +59,10 @@ public class MoviesRepositoryTest {
}
@Test
public void testRateMovie() throws Exception {
Movie movie = new Movie("1", "Test-Movie").persist();
User user=new User("me","me","me").persist();
user.rate(movie, 5, "comment");
Movie movie = movieRepository.save(new Movie("1", "Test-Movie"));
User user = userRepository.save(new User("me", "me", "me"));
user.rate(template, movie, 5, "comment");
movie = movieRepository.findById("1");
final Rating rating = IteratorUtil.first(movie.getRatings());
assertEquals("rating stars", 5, rating.getStars());
assertEquals("rating comment", "comment", rating.getComment());
@@ -68,9 +72,9 @@ public class MoviesRepositoryTest {
@Test
public void testFindTwoMovies() throws Exception {
Movie movie1 = new Movie("1", "Test-Movie1").persist();
Movie movie2 = new Movie("2", "Test-Movie2").persist();
Movie movie3 = new Movie("3", "Another-Movie3").persist();
Movie movie1 = movieRepository.save(new Movie("1", "Test-Movie1"));
Movie movie2 = movieRepository.save(new Movie("2", "Test-Movie2"));
Movie movie3 = movieRepository.save(new Movie("3", "Another-Movie3"));
List<Movie> found = movieRepository.findByTitleLike("Test*", new PageRequest(0, 2)).getContent();
assertEquals("2 movies found", 2, found.size());
assertEquals("2 correct movies found by query", new HashSet<Movie>(asList(movie1, movie2)), new HashSet<Movie>(found));
@@ -78,9 +82,9 @@ public class MoviesRepositoryTest {
@Test
public void testFindTwoMoviesButRestrictToOne() throws Exception {
Movie movie1 = new Movie("1", "Test-Movie1").persist();
Movie movie2 = new Movie("2", "Test-Movie2").persist();
Movie movie3 = new Movie("3", "Another-Movie3").persist();
Movie movie1 = movieRepository.save(new Movie("1", "Test-Movie1"));
Movie movie2 = movieRepository.save(new Movie("2", "Test-Movie2"));
Movie movie3 = movieRepository.save(new Movie("3", "Another-Movie3"));
List<Movie> found = movieRepository.findByTitleLike("Test*", new PageRequest(0, 1)).getContent();
assertEquals("1 movie found",1,found.size());
assertTrue("1 correct movie found by query", found.get(0).getTitle().startsWith("Test"));