I wanted to find out which all person nodes are associated to a given Movie and in what roles. Consider that my Movie database has several relations -
Person acted in a movie
Person directed a movie
Person reviewed a movie
Person followed a movie ......... and many more.
In a relational database this would probably be setup as separate tables - ACTED table, DIRECTED table etc each of which would map the Person's primary key and the movies key. In Neo4j relations played the role. But If I wanted to find out all of theses above results would I have to fire a separate query for each type of relation ?
Something like
Fortunately CYPHER provides a very useful type keyword. The same result can be obtained with a single query as seen below:
Cypher agains come to our rescue with the labels keyword:
Person acted in a movie
Person directed a movie
Person reviewed a movie
Person followed a movie ......... and many more.
In a relational database this would probably be setup as separate tables - ACTED table, DIRECTED table etc each of which would map the Person's primary key and the movies key. In Neo4j relations played the role. But If I wanted to find out all of theses above results would I have to fire a separate query for each type of relation ?
Something like
MATCH (a:Person)-[:ACTED_IN]->(m:Movie) WHERE m.title='Cloud Atlas' RETURN a MATCH (a:Person)-[:DIRECTED]->(m:Movie) WHERE m.title='Cloud Atlas' RETURN a MATCH (a:Person)-[:REVIEWED]->(m:Movie) WHERE m.title='Cloud Atlas' RETURN aThis would mean firing n cypher queries and processing each result separately. This would be a very inefficient way to do it. Also as the number of possible relations grow, change the code would have to be updated.
Fortunately CYPHER provides a very useful type keyword. The same result can be obtained with a single query as seen below:
public Map<String, String> getAssociationsToMovie(String movieName, int released) { try (Transaction tx = graphDb.beginTx()) { Map<String, Object> params = new HashMap<>(); params.put("mName", movieName); params.put("releasedYear", released); Result result = graphDb.execute( "MATCH (p:Person)-[r]->(m:Movie) WHERE m.title='Cloud Atlas' RETURN p.name AS pName, type(r) as assocn", params); if (!result.hasNext()) { return null; } Map<String, String> soln = new HashMap<>(); while (result.hasNext()) { Map<String, Object> row = result.next(); String pName = (String) row.get("pName"); String assocn = (String) row.get("assocn"); soln.put(pName, assocn);// assuming person has only one relationship to // a given Movie } return soln; } }I tested the same as below:
public static void main(String[] args) { MovieDAO movieDAO = new MovieDAO(); Map<String, String> result = movieDAO.getAssociationsToMovie("Cloud Atlas", 2012); result.keySet().forEach(key -> System.out.println(key + " - " + result.get(key) )); }The output of the above code is:
Lana Wachowski - DIRECTED Tom Hanks - ACTED_IN Tom Tykwer - DIRECTED Hugo Weaving - ACTED_IN Halle Berry - ACTED_IN Stefan Arndt - PRODUCED Jim Broadbent - ACTED_IN Jessica Thompson - REVIEWED Andy Wachowski - DIRECTED David Mitchell - WROTESimilarly consider the case that we have various type of Nodes all asociated with a movie. And we would like to fetch them all in a single query. How do we identify the label of the node ?
Cypher agains come to our rescue with the labels keyword:
MATCH (a)-[r]->(m:Movie) WHERE m.title='Cloud Atlas' RETURN labels(a) as NodeType, aThe output of the code gives the values as seen here
This comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete