Hidden GraphGems revisited: the 2.2 Meta-graph


Originally posted on Rik’s Blog

The 2.2 Meta-graph

Last week I shared this great little gem of a Cypher query that would allow you to very quickly to take a view at the Model of an existing Neo4j database. This was the query that we ran to generate the Meta-graph:
 
 // generate the pre-2.2 META-graph  
 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  
That gave us a visualisation in the Neo4j browser that looked like this:
Nice, but not really. It’s a little awkward, actually, as it uses nodes to represent Node-labels (makes sense!), but also uses nodes to represent relationship-types (makes a lot less sense). I mean, it was useful and nice, but we want and need better than that.
 
Turns out that one of the main reasons that Michael originally created this query this way, was that he needed a way to “visualise” the relationship names. In previous versions of Neo4j, the browser did not allow you to choose the relationship property to use on the relationship – and now it does. So … we could revisit the Meta-graph query, right? Right!
 

The Meta-graph as from Neo4j 2.2

There have been a LOT of improvements in Neo4j 2.2, most under the hood – but some are very visible in the Neo4j browser. One of the new things is that you can choose the property to put on the relationships in the graph view of the browser. Seems trivial, but if we make a couple of small tweaks to the Meta-graph query, it gets a whole lot better:
 
 // generate the 2.2 META-graph  
  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:Meta_Node {name:l})   
  MERGE (b:Meta_Node {name:l2})   
  MERGE (a)-[:META_RELATIONSHIP {name:rel_type}]->(b)   
  RETURN distinct l as first_node, rel_type as connected_by, l2 as second_node   
Instead of creating a node for every relationship, it now just … creates a relationship for every relationship type, and adds a “name” property to the META_RELATIONSHIP relationship type. That’s the property that we can then select in the new browser to create a visualisation like this one:
How much nicer is that? A lot, if you ask me. So take it for a spin, and let me know what you think. I for one like it 🙂 Cheers Rik