From 44e667d8349ec574f654da01cfcc6c53e54800c2 Mon Sep 17 00:00:00 2001 From: Michael Hunger Date: Mon, 4 Apr 2011 12:07:01 +0200 Subject: [PATCH] updated docs, added recommendation to tutorial --- .../reference/programming-model/aspectj.xml | 4 +- src/docbkx/tutorial/recommendations.xml | 75 ++++++++++++++----- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/docbkx/reference/programming-model/aspectj.xml b/src/docbkx/reference/programming-model/aspectj.xml index 24680b7ff..786b1c02f 100644 --- a/src/docbkx/reference/programming-model/aspectj.xml +++ b/src/docbkx/reference/programming-model/aspectj.xml @@ -35,7 +35,9 @@ Eclipse and STS support AspectJ via the AJDT plugin which can be installed from the update-site: - + http://download.eclipse.org/tools/ajdt/36/update/ + (or for the latest development snapshot of the plugin + http://download.eclipse.org/tools/ajdt/36/dev/update). The AspectJ support in IntelliJ IDEA lacks some of the features. JetBrains is working to improve the situation diff --git a/src/docbkx/tutorial/recommendations.xml b/src/docbkx/tutorial/recommendations.xml index 657331afd..48e4860a6 100644 --- a/src/docbkx/tutorial/recommendations.xml +++ b/src/docbkx/tutorial/recommendations.xml @@ -3,25 +3,60 @@ Movies! Friends! Bargains! - Recommendations - In the last part of this exercise we wanted to add recommendations to the app. One obvious recommendation is movies that our friends liked - (and their friends too, but with less importance). The second was recommendations for new friends that also liked the movies that we liked most. - - Doing this kind of ranking algorithms is really fun with graph databases. They are applied to the graph by traversing it in a certain order, collecting information - on the go and deciding which paths to follow and what to include in the results. - - Lets say I'm only interested in the top 10 recommendations each. - - 5) return EXCLUDE_AND_STOP; - Relationship rating = path.lastRelationship(); - if (rating.getType().equals(RATED)) { - rating.getProperty() - return INCLUDE_AND_STOP; - } - return INCLUDE_AND_CONTINUE; - }) -]]> + In the last part of this exercise we wanted to add recommendations to the app. One obvious recommendation is + movies that our friends liked + (and their friends too, but with less importance). The second was recommendations for new friends that also + liked the movies that we liked most. + + + Doing this kind of ranking algorithms is really fun with graph databases. They are applied to the graph by + traversing it in a certain order, collecting information on the go and deciding which paths to follow and what + to include in the results. + + + Lets say we're only interested in the recommendations of a certain degree of friends. + + + recommendMovies(User user, final int ratingDistance) { + final DynamicRelationshipType RATED = withName(User.RATED); + final Map ratings=new HashMap(); + TraversalDescription traversal= Traversal.description().breadthFirst() + .relationships(withName(User.FRIEND)).relationships(RATED, OUTGOING).evaluator(new Evaluator() { + + public Evaluation evaluate(Path path) { + final int length = path.length() - 1; + if (length > ratingDistance) return Evaluation.EXCLUDE_AND_PRUNE; // only as far as requested + Relationship rating = path.lastRelationship(); + if (rating != null && rating.getType().equals(RATED)) { // process RATED relationships, not FRIEND + if (length == 0) return Evaluation.EXCLUDE_AND_PRUNE; // my rated movies + final long movieId = rating.getEndNode().getId(); + int[] stars = ratings.get(movieId); + if (stars == null) { + stars = new int[2]; + ratings.put(movieId, stars); + } + int weight = ratingDistance - length; // aggregate for averaging, inverse to distance + stars[0] += weight * (Integer) rating.getProperty("stars", 0); + stars[1] += weight; + return Evaluation.INCLUDE_AND_PRUNE; + } + return Evaluation.EXCLUDE_AND_CONTINUE; + } + }); + + Map result=new HashMap(); + final Iterable movies = movieRepository.findAllByTraversal(user, traversal); // lazy traversal results + for (Movie movie : movies) { // assign movie to averaged rating + final int[] stars = ratings.get(movie.getNodeId()); + result.put(movie, stars[0]/stars[1]); + } + return result; +} + ]]> + + + The UserController just calls this method, adds it's results to the the model and the view renders the + recommendation alongside with your own ratings.