Skip to content

Instantly share code, notes, and snippets.

@jexp
Last active January 15, 2018 16:18
Show Gist options
  • Save jexp/9c4cb9e842ed24a3feae to your computer and use it in GitHub Desktop.
Save jexp/9c4cb9e842ed24a3feae to your computer and use it in GitHub Desktop.
The Meta-Graph - Create a Meta-Representation of your Neo4j-Graph-Database

Finally: The Meta-Graph

This week, Dave Poole published introductory but insightful article on Neo4j where he used SQL-Views on System tables to generate Cypher statements that insert the database meta data into Neo4j for further inspection.

Getting more insights about the overall structure of your Graph Database is a common need among our users, I published an article a while ago, that used the Neo4j-Shell and some JavaScript driving the Core-API to achieve this goal.

After our data model training, our dutch trainer Ron van Weverwijk, posed that question again, being one of the obstacles for attendees of our classes.

Then it made click and I thought: "That’s supereasy to do in Cypher itself"

Sample Database: Worldcup

As sample database I want to use a variant of our WorldCup dataset. For lack of other data on the plane, I used the match Germany vs. Portugal.

MERGE (year:Year {year: 2014})
MERGE (host:Country {name: "Brazil"})

MERGE (worldCup:WorldCup {name: "WorldCup "+host.name+" "+year.year})
MERGE (host)<-[:HOSTED_BY]-(worldCup)
MERGE (year)<-[:IN_YEAR]-(worldCup)

MERGE (stadium:Stadium {name: "Arena Fonte Nova, Salvador"})
MERGE (stadium)-[:STADIUM_OF]->(worldCup)

MERGE (home:Country {name: "Germany"})
MERGE (worldCup)<-[:PARTICIPATED_IN]-(homeTeam:Team {name: "Team "+home.name+" in "+worldCup.name})<-[:NAMED_TEAM]-(home)

MERGE (away:Country {name: "Portugal"})
MERGE (worldCup)<-[:PARTICIPATED_IN]-(awayTeam:Team {name: "Team "+away.name+" in "+worldCup.name})<-[:NAMED_TEAM]-(away)

MERGE (worldCup)-[:CONTAINS]->(match:Match {id: "G"}) ON CREATE SET match.name = home.name +" vs "+away.name

MERGE (match)-[:PLAYED_IN_STADIUM]->(stadium)
MERGE (match)-[:HOME_TEAM]->(homeTeam)
MERGE (match)-[:AWAY_TEAM]->(awayTeam)

FOREACH (p IN ["Müller","Götze","Özil","Khedira","Höwedes","Boateng","Mertesacker","Hummels","Lahm","Kroos","Neuer"] |
   MERGE (player:Player {name:p})
   MERGE (player)-[:IN_TEAM]->(homeTeam)
   MERGE (player)-[:PLAYED_IN]->(match)
)

FOREACH (p IN ["Patricio","Pepe","Alves","Coentrao","Meireles","Ronaldo","Almeida","Moutinho","Nani","Pereira","Veloso"] |
   MERGE (player:Player {name:p})
   MERGE (player)-[:IN_TEAM]->(awayTeam)
   MERGE (player)-[:PLAYED_IN]->(match)
)

FOREACH (goal IN [{name:"Müller",minutes:12},{name:"Hummels",minutes:32},{name:"Müller",minutes:45},{name:"Müller",minutes:78}] |
   MERGE (player:Player {name:goal.name})
   MERGE (player)<-[:SCORED_GOAL {time:goal.minutes}]-(match)
);

A tiny slice of the WorldCup-Graph looks like this, the real dataset has all WorldCups, Players, Matches, Scores and Countries.

About the Meta-Graph

After all it was pretty simple to create the meta-graph, this query is similar to the one "What is connected and how, that you find in the Neo4j-Browser-Sidebar", which looks like this.

MATCH (a)-[r]->(b)
WITH labels(a) AS a_labels,type(r) AS rel_type,labels(b) AS b_labels
RETURN distinct *
LIMIT 100;

Making of the Meta-Graph

We can use this result easily to create a network of :Node:Meta and :Relationship:Meta nodes representing the graph structure of our domain.

MATCH (a)-[r]->(b)
WITH labels(a) AS a_labels,type(r) AS rel_type,labels(b) AS b_labels
UNWIND a_labels as l
UNWIND b_labels as l2
MERGE (a:Node:Meta {name:l})
MERGE (b:Node:Meta {name:l2})
MERGE (a)-[:OUTGOING]->(:Relationship:Meta {name:rel_type})-[:INCOMING]->(b)
RETURN distinct l as first_node, rel_type as connected_by, l2 as second_node

Show the Meta-Graph

MATCH (m:Meta)-[r]-()
RETURN m,r

So you can clearly see the nodes and the relationships that connect them in this meta-graph representation.

Further ideas:

  • make a virtual d3-visualization of the database meta-information part of Neo4j Browser

  • actually generate textual Cypher like Dave did to also add Labels, Relationshiptypes and Properties as such to the meta-graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment