1
votes

The example on the online course calls for 3 Recommended actors that Keanu Reeves should work with but hasn't, the solution in that example is demonstrated as:

MATCH (keanu:Person {name:"Keanu Reeves"})-[:ACTED_IN]->()<-[:ACTED_IN]-(c),
      (c)-[:ACTED_IN]->()<-[:ACTED_IN]-(coc)
WHERE coc <> keanu  AND NOT((keanu)-[:ACTED_IN]->()<-[:ACTED_IN]-(coc))
RETURN coc.name, count(coc)
ORDER BY count(coc) DESC
LIMIT 3;

The results of the above

Tom Hanks   4
Stephen Rea 3
John Hurt   3

However, Tom Hanks played in 12 movies according to the sample database. Further more there's higher ranked movie stars like Meg Ryan that is not on that list.

My solution was this cypher

match (other:Person)-[:ACTED_IN]->(movie),
(keanu:Person {name:'Keanu Reeves'})
WHERE
NOT (keanu)-[:ACTED_IN]->(movie)
return other.name, count(movie)
order by count(movie) desc
limit 3;

Which results in the following:

Tom Hanks   12
Meg Ryan    5
Jack Nicholson  4

Am I missing something? Or is the example solution provided is not accurate.

I'm a total beginner to Neo4j so forgive me if I'm totally off my rocker.

2

2 Answers

2
votes

The solution provided is called collaborative filtering, ie. what did people that liked what I liked also liked. This approach is based on finding a "peer group" to yourself.

What you propose is a metric based on popularity or frequency.

Real world recommendations are based on a number of aspects depending on your requirements and use-cases.

See this presentation for an intro: http://de.slideshare.net/bachmanm/recommendations-with-neo4j-fosdem-2015

0
votes

Actually, you did not understand the task correctly (so did I for the first time!)

The author of the question actually asked: find three actors that acted in movies WITH actors that acted in the movies with Keanu Reeves AND still have NOT acted in any movie with Keanu himself.

And you solved the problem: find three of the most filmed actors that have not still acted in the same movie with Keanu Reeves

Surely, shame on the question author for the ambiguous formulation!

By the way, I wish to present you my alternative solution that looks a bit shorter than provided by author:

MATCH (actor:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(keanu:Person {name: "Keanu Reeves"}),
(other:Person)-[:ACTED_IN]->(movie)<-[:ACTED_IN]-(actor)
WHERE NOT (movie)<-[:ACTED_IN]-(keanu:Person {name: "Keanu Reeves"})
RETURN other.name, COUNT(*) as Movies
ORDER BY Movies DESC
LIMIT 3;
    ╒═══════════════╤════════╕
    │"other.name"   │"Movies"│
    ╞═══════════════╪════════╡
    │"Tom Hanks"    │4       │
    ├───────────────┼────────┤
    │"Jim Broadbent"│3       │
    ├───────────────┼────────┤
    │"Halle Berry"  │3       │
    └───────────────┴────────┘