Search This Blog

Saturday 5 May 2018

Neo4j - extracting some schema information using Cypher queries

Since schema is not a compulsion with Neo4j, I was looking at ways to get information on the type of nodes and relationships in the database.
These below are not my own queries. I came across a good link and decided to use it here.
The below java code when executed against a database collect information on the type of nodes, relations and combinations seen in the database.

public class SchemaInformationReader {

  private static final String DB_LOCATION = "E:\\neo4jData\\21Dec2015";

  final GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();

  {
    dbFactory.setUserLogProvider(new Slf4jLogProvider());
  }

  final GraphDatabaseService graphDb;

  public SchemaInformationReader(String location) {
    graphDb = dbFactory.newEmbeddedDatabase(new File(location));
  }

  public void collectGraphInfo(Writer writer) throws IOException {
    String lineSeparator = System.lineSeparator();
    writer.write("------------------Result------------------");
    try (Transaction tx = graphDb.beginTx()) {
      Result result = graphDb.execute("match (n) return distinct labels(n) as nodeLabel");
      if (!result.hasNext()) {
        writer.write(lineSeparator + "No Labels found in the database");
      } else {
        writer.write(lineSeparator + "Labels::::::::::::");
        int i =0;
        while (result.hasNext()) {
          i++;
          writer.write(lineSeparator + result.next().get("nodeLabel"));
        }
        writer.write(lineSeparator + "Total Labels : " + i);
      }

      result = graphDb.execute("match ()-[r]-() return distinct type(r) as reln");
      if (!result.hasNext()) {
        writer.write(lineSeparator + "No Relations found in the database");
      } else {
        writer.write(lineSeparator + "Relations::::::::::::");
        int i =0;
        while (result.hasNext()) {
          i++;
          writer.write(lineSeparator + result.next().get("reln"));
        }
        writer.write(lineSeparator + "Total Labels : " + i);
      }

      result = graphDb.execute("match (n)-[r]-() return distinct labels(n) as nodeLabel, type(r) as reln");
      if (!result.hasNext()) {
        writer.write(lineSeparator + "No Node, Relation combinations found in the database");
      } else {
        writer.write(lineSeparator + "Relations::::::::::::");
        int i =0;
        while (result.hasNext()) {
          Map<String, Object> record = result.next();
          i++;
          writer.write(lineSeparator + record.get("nodeLabel") + ", " + record.get("reln"));
        }
        writer.write(lineSeparator + "Node, Relation combinations : " + i);
      }

    }
    writer.write(lineSeparator + "------------------ ------------------");
  }

  private void exit() {
    graphDb.shutdown();
  }

  public static void main(String[] args) throws IOException {
    SchemaInformationReader informationReader = new SchemaInformationReader(DB_LOCATION);
    Writer stringWriter = new StringWriter();
    informationReader.collectGraphInfo(stringWriter);
    System.out.println(stringWriter.toString());
    informationReader.exit();
  }

}
The collectGraphInfo method is where all the heavy lifting happens. There are three queries here:
  1. The first query retrieves all Labels in the graph
  2. The second query retrieves all the Relationships in the graph
  3. The third one identifies every Label Relationship query that has been created in the graph.
I executed this against the movie database present in Neo4j. The output on execution of the main method:
------------------Result------------------
Labels::::::::::::
[Movie]
[Person]
Total Labels : 2
Relations::::::::::::
ACTED_IN
PRODUCED
DIRECTED
WROTE
REVIEWED
FOLLOWS
Total Labels : 6
Relations::::::::::::
[Movie], ACTED_IN
[Movie], PRODUCED
[Movie], DIRECTED
[Movie], WROTE
[Movie], REVIEWED
[Person], ACTED_IN
[Person], PRODUCED
[Person], WROTE
[Person], DIRECTED
[Person], FOLLOWS
[Person], REVIEWED
Node, Relation combinations : 11
------------------ ------------------

No comments:

Post a Comment