Generic Graph Model

Wolfgang Schuetzelhofer edited this page Jul 31, 2017 · 4 revisions
Previous Next Table of Contents

Generic Graph Model

JCypher provides a generic graph model. The model consists of nodes, relations, and paths, together with properties, labels, and types. While simple, the model allows to easily navigate and manipulate graphs.
On the one hand a graph model is created if you execute a query (a JCypher-Query-DSL query) against a graph database. On the other hand you can create a graph model, starting with an empty one, completely from scratch.
In either case you can modify and navigate the model, and you can store the modified model to the database.
The root package for graph model related classes is iot.jcypher.graph.

IDBAccess dbAccess = // create an IDBAccess
JcQuery query = // create a query

/** execute the query against a Neo4j database */
JcQueryResult result = dbAccess.execute(query);
// handle errors
if (result.hasErrors())
   printErrors(result);

You can ask an instance of JcQueryResult for errors that might have occurred during processing a query, and you can retrieve the results of the query. For the latter purpose JcQueryResult provides a couple of methods which return the actual result or parts of the result in form of the upper mentioned graph model.
These methods are all named resultOf(...), take an instance of a value class (JcNode, JcRelation, JcPath, JcNumber, ...) as an argument, and return a list of elements of the result model (i.e. the graph model) (GrNode, GrRelation, GrPath, ...).
Note: Every argument used in a resultOf(...) method must have been declared in the context of the query and must have been listed in one of the RETURN clauses of the query (though by using RETURN.ALL() you don't have to list every single return value).

JcNode actor = new JcNode("actor"); 
JcQuery query = new JcQuery(); 
query.setClauses(new IClause[] { 
   MATCH.node(actor).relation().out().type("ACTS_IN").node(), 
   RETURN.value(actor) 
}); 
JcQueryResult result = dbAccess.execute(query); 
List<GrNode> actors = result.resultOf(actor);

Note: An additional method of JcQueryResult is resultMapListOf(JcPrimitive... key), which returns a list of lteral maps. As with the other result methods, every argument used in the resultMapListOf(...) method must have been declared in the context of the query and must have been listed in one of the RETURN clauses. A literal map as contained in such a list is a map of key/value pairs. The values can only be literals (primitive values). To access such a value, you can use the appropriate key (one of those used when invoking the resultMapListOf(...)), or you can use that key's name (i.e. the name you provided when creating the JcPrimitive).

JcNode actor = new JcNode("actor");
JcString firstName = new JcString("firstName");
JcString lastName = new JcString("lastName");
JcQuery query = new JcQuery(); 
query.setClauses(new IClause[] { 
   MATCH.node(actor).relation().out().type("ACTS_IN").node(), 
   RETURN.value(actor.property("firstName")).AS(firstName),
   RETURN.value(actor.property("lastName")).AS(lastName) 
}); 
JcQueryResult result = dbAccess.execute(query); 
LiteralMapList mapList = result.resultMapListOf(firstName, lastName);
// retrieve the first map in the list where 'lastname' equals 'Reeves'
LiteralMap map = mapList.selectFirst(lastName, "Reeves");
// now get the 'firstName' value
String fn = map.get(firstName);

Elements of a graph model are: GrNode, GrRelation, GrPath, GrProperty, GrLabel. Elements of the graph model returned by a query can be modified (i.e. labels and properties can be added or removed from nodes or relations, properties can be modified). An element of the graph can be removed by calling method remove() on that element. With the next update to the graph database such elements will be removed from the database.

Class Graph builds the container for graph elements. You can retrieve an instance of Graph either from a GrNode or a GrRelation or from the JcQueryResult by calling method getGraph(). Or you can create a new, empty graph by calling the static method Graph.create(dbAccess). If you have retrieved an instance of class Graph, you can use it to create new nodes and/or relations, and you can use it to update the underlying database with changes made on the graph model.

JcQueryResult result = dbAccess.execute(query); 
List<GrNode> actors = result.resultOf(actor);

GrNode keanu = actors.get(0);
// remove a node
keanu.remove();

GrNode laurence = actors.get(1);
// modify a property
laurence.getProperty("firstName").setValue("George");

// retrieve the Graph (container of the graph model)
Graph graph = result.getGraph();

// store the modified graph
List<JcError> errors = graph.store();

// handle errors
if (!errors.isEmpty())
   printErrors(errors);

You can start with a new (empty) graph model.

// create a new graph model
Graph graph = Graph.create(dbAccess);

// create a node
GrNode matrix = graph.createNode();
// add a label
matrix.addLabel("Movie");
// add properties
matrix.addProperty("title", "The Matrix");
matrix.addProperty("year", "1999-03-31");

// create another node
GrNode keanu = graph.createNode();
keanu.addLabel("Actor");
keanu.addProperty("name", "Keanu Reeves");

// create a relation
GrRelation rel = graph.createRelation("ACTS_IN", keanu, matrix);
rel.addProperty("role", "Neo");

// store the graph
List<JcError> errors = graph.store();
// handle errors
if (!errors.isEmpty())
   printErrors(errors);

Previous Next Table of Contents