Neo4j Graph Database
Seminar 5 of NoSQL Databases (PA195)�
David Novak, FI, Masaryk University, Brno
Agenda
Graph Databases: Example
source: Sadalage & Fowler: NoSQL Distilled, 2012
Graph Databases: Mission
Graph Databases: Representatives
Ranked list: http://db-engines.com/en/ranking/graph+dbms
Neo4j: Basic Info
Data Model: Nodes
Data Model: Properties
Type | Description |
boolean | true/false |
byte | 8-bit integer |
short | 16-bit integer |
int | 32-bit integer |
long | 64-bit integer |
float | 32-bit IEEE 754 floating-point number |
double | 64-bit IEEE 754 floating-point number |
char | 16-bit unsigned integers representing Unicode characters |
String | sequence of Unicode characters |
Data Model: Relationships
Neo4j in Server mode
$ ssh root@... -L 7474:localhost:7474 -L 7687:localhost:7687
neo4j-community-3.1.4# ./bin/neo4j start
Neo4j in Server mode (2)
Web Interface
Cypher Language
Cypher: Clauses
Cypher: Creating Nodes (Examples)
CREATE (n);
(create a node, assign to var n)
Created 1 node, returned 0 rows
CREATE (a: Person {name : 'Jan'}) RETURN a;
(create a node with label ‘Person’ and ‘name’ property Jan’)
Created 1 node, set 1 property, returned 1 row
Cypher: Creating Relationships
START a=node(1), b=node(2)
CREATE (a)-[r:RELTYPE]->(b)
RETURN r ;
(create relations RELTYPE between nodes with IDs 1 and 2)
Created 1 relationship, returned 1 row
START a=node(1), b=node(2)
CREATE (a)-[r:RELTYPE {name : a.name + '->' + b.name }]->(b)
RETURN r
(set property ‘name’ of the relationship)
Created 1 node, set 1 property, returned 1 row
Cypher: Creating Paths
CREATE p = (andres: Person {name: 'Andres'})-[:WORKS_AT]->(neo)<- [:WORKS_AT]-(michael: Person {name:'Michael'})
RETURN p ;
(all parts of the pattern are created, if not existing)�
P [Node[4]{name:"Andres"},:WORKS_AT[2] {},Node[5]{},:WORKS_AT[3] {},Node[6]{name:"Michael"}]
1 row
Nodes created: 3
Relationships created: 2
Properties set: 2
Cypher: Changing Properties
MATCH (n: Person {name: 'Andres'})
SET n.surname = 'Taylor'
RETURN n
(find a node with name ‘Andres’ and set it surname ‘Taylor’)�
n Node[0]{name:"Andres",surname:"Taylor"}
1 row
Properties set: 1
Cypher: Queries
MATCH (user: Person {name: 'Andres'})-[:FRIEND]->(follower)
RETURN user.name, follower.name
(find all ‘friends’ of 'Andres')
MATCH (p: Person)
WHERE p.age > 18 AND p.age < 30
RETURN p.name
(return names of all adult people under 30)
Task: modify the nodes so that these queries return something:
Cypher: Queries (2)
MATCH (andres: Person {name: 'Andres'})-[*1..3]-(node)
RETURN andres, node ;
(find all ‘nodes’ within three hops from ‘Andres’)
MATCH p=shortestPath(
(andres:Person {name: 'Andres'})-[*]-(david {name:'David'})
)
RETURN p ;
(find the shortest connection between ‘Andres’ and ‘David’)
Cypher: Delete
MATCH (n: Person {name: 'Andres'})
DELETE n
(delete all Persons with name ‘Andres’)
�Cannot delete node<3>, because it still has relationships.
MATCH (n: Person {name: 'Andres'}), ((n)-[r]-())
DELETE r,n
(first, we must delete all relationships of node with name ‘Andres’)
Nodes deleted: 1
Relationships deleted: 1
Neo4j Web UI: Demo
Neo4j Shell
REST API
�curl -i -X POST http://localhost:7474/db/data/node -H "Content-Type: application/json; charset=UTF-8" --user "neo4j" -d '{ "name": "Jan" }'
Neo4j as Embedded Database
$ tar xvzf neo4j-excercise.tgz
$ module add idea-2017.2
$ idea.sh
Neo4j: “Hello World” – Java API
String PATH="some_directory";
GraphDatabaseService graphDb;
// starting a database
graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(new File(PATH));
Node firstNode, secondNode;
Relationship relationship;
Neo4j: “Hello World” (2)
// create a small graph:
firstNode = graphDb.createNode();
firstNode.setProperty( "message", "Hello, " );
secondNode = graphDb.createNode();
secondNode.setProperty( "message", "World!" );
relationship = firstNode.createRelationshipTo
(secondNode,
RelationshipType.withName("KNOWS"));
relationship.setProperty
("message", "brave Neo4j ");
Neo4j: Transactions
// all writes (creating, deleting and updating any data)
// have to be performed in a transaction:
try (Transaction tx = graphDb.beginTx()) {
(…)
// print the result:
System.out.print(firstNode.getProperty("message"));
System.out.print(relationship.getProperty("message"));
System.out.println(secondNode.getProperty("message"));
// transaction operations
tx.success();
}
Data Model: Path & Traversal
Traversal Framework
Traversal = TraversalDescription + starting node(s)
Traversal Framework – Java API
Traversal Framework – Java API (2)
Traversal Framework – Java API (3)
Find All “Admins”
Node admins = getNodeByName( "Admins" );
TraversalDescription desc = graphDb.traversalDescription()
.breadthFirst()
.evaluator( Evaluators.excludeStartPosition() )
.relationships(RoleRels.PART_OF, Direction.INCOMING)
.relationships(RoleRels.MEMBER_OF, Direction.INCOMING);
Traverser traverser = desc.traverse(admins);
StringBuilder output = new StringBuilder();�
for ( Node node : traverser.nodes() ) {
output.append("Found: ")
.append(node.getProperty(NAME))
.append(" at depth: ")
.append(path.length()).append("\n");
}
Found: HelpDesk at depth: 1
Found: Ali at depth: 1
Found: Engin at depth: 2
Found: Demet at depth: 2
Task 2. Get Group Membership of a User
Node jale = getNodeByName( "Jale" );
desc = graphDb.traversalDescription()
.depthFirst()
.evaluator( Evaluators.excludeStartPosition() )
.relationships(RoleRels.MEMBER_OF, Direction.OUTGOING)
.relationships(RoleRels.PART_OF, Direction.OUTGOING);
traverser = traversalDescription.traverse( jale );
Found: ABCTechnicians at depth: 1
Found: Technicians at depth: 2
Found: Users at depth: 3
Task 3. Get All Groups
Node referenceNode = getNodeByName( "Reference_Node" ) ;
desc = graphDb.traversalDescription()
.breadthFirst()
.evaluator( Evaluators.excludeStartPosition() )
.relationships(RoleRels.ROOT, Direction.INCOMING )
.relationships(RoleRels.PART_OF, Direction.INCOMING);
traverser = desc.traverse( referenceNode );
Found: Admins at depth: 1
Found: Users at depth: 1
Found: HelpDesk at depth: 2
Found: Managers at depth: 2
Found: Technicians at depth: 2
Found: ABCTechnicians at depth: 3
Task 4. Get All Members in the Database
Node referenceNode = getNodeByName( "Reference_Node" ) ;
desc = graphDb.traversalDescription()
.breadthFirst()
.evaluator(Evaluators.includeWhereLastRelationshipTypeIs
(RoleRels.MEMBER_OF ));
traverser = �desc.traverse( referenceNode );
Found: Ali at depth: 2
Found: Engin at depth: 2
Found: Burcu at depth: 2
Found: Can at depth: 2
Found: Demet at depth: 3
Found: Gul at depth: 3
Found: Fuat at depth: 3
Found: Hakan at depth: 3
Found: Irmak at depth: 3
Found: Jale at depth: 4
Access to Nodes
Node ali = � graphDb.findNode(Label.label("Person"), "name", "Ali");
Task: Movies in Embedded Mode
Movies in Embedded Mode (2)
Questions?
Please, any questions? Good question is a gift...�
References