Database Reference
In-Depth Information
The following listing shows a solution to the same problem as before—finding movies
that John's friends have seen but John hasn't—but this time using only the Java for loop
constructs over the Neo4j Iterable implementation, without unnecessary memory con-
sumption in local variables.
Listing 4.5. Using iterables to lower Java heap memory consumption
Node userJohn = graphDb.getNodeById(JOHN_JOHNSON_NODE_ID);
Set<Node> moviesFriendsLike = new HashSet<Node>();
for (Relationship r1 :
userJohn.getRelationships(IS_FRIEND_OF)) {
Node friend = r1.getOtherNode(userJohn);
for (Relationship r2 :
friend.getRelationships(Direction.OUTGOING, HAS_SEEN)) {
Node movie = r2.getEndNode();
boolean johnLikesIt = false;
for (Relationship r3 :
movie.getRelationships(Direction.INCOMING, HAS_SEEN)) {
if (r3.getStartNode().equals(userJohn)) {
johnLikesIt = true;
}
}
if (!johnLikesIt) {
moviesFriendsLike.add(movie);
}
}
}
for (Node movie : moviesFriendsLike) {
logger.info("Found movie: " + movie.getProperty("name"));
}
Note
While this solution looks better, there's a potential performance bottleneck for movies that
have been seen by millions of users (because you check whether John has already seen
the movie in each loop iteration). This won't have an impact on our limited data set, but it
points out that for large data sets, it sometimes may be better to write simpler code, even
if that means writing more of it. In this example, you could find all movies John has seen
once up front, and then use that set to filter out movies in the for loop.
 
Search WWH ::




Custom Search