Presented at JAX London
In this session we'll look at some of the design and implementation strategies you can employ when building a Neo4j-based graph database solution, including architectural choices, data modelling, and testing.
17. Models
Purposeful
abstrac@on
of
a
domain
designed
to
sa@sfy
par@cular
applica@on/end-‐user
goals
Images:
en.wikipedia.org
18. Applica@on/End-‐User
Goals
As
an
emp
loyee
I
want
to
k
now
who
i
n
the
comp
has
similar
any
skills
to
m
e
So
that
we
can
excha
nge
knowl
edge
19. Ques@ons
To
Ask
of
the
Domain
As
an
emp
loyee
I
want
to
k
now
who
i
n
the
co
has
similar
skills
to
me mpany
So
that
we
can
excha
nge
knowle
dge
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
20. Iden@fy
En@@es
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
Person
Company
Skill
21. Iden@fy
Rela@onships
Between
En@@es
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
Person
WORKS_FOR
Company
Person
HAS_SKILL
Skill
22. Convert
to
Cypher
Paths
Rela@onship
Person
WORKS_FOR
Company
Person
HAS_SKILL
Skill
Label
(:Person)-[:WORKS_FOR]->(:Company),
(:Person)-[:HAS_SKILL]->(:Skill)
25. Express
Ques@on
as
Graph
Pa$ern
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
26. Cypher
Query
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
MATCH (company)<-[:WORKS_FOR]-(me:Person)-[:HAS_SKILL]->(skill),
(company)<-[:WORKS_FOR]-(colleague)-[:HAS_SKILL]->(skill)
WHERE me.name = {name}
RETURN colleague.name AS name,
count(skill) AS score,
collect(skill.name) AS skills
ORDER BY score DESC
27. Graph
Pa$ern
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
MATCH (company)<-[:WORKS_FOR]-(me:Person)-[:HAS_SKILL]->(skill),
(company)<-[:WORKS_FOR]-(colleague)-[:HAS_SKILL]->(skill)
WHERE me.name = {name}
RETURN colleague.name AS name,
count(skill) AS score,
collect(skill.name) AS skills
ORDER BY score DESC
28. Anchor
Pa$ern
in
Graph
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
MATCH (company)<-[:WORKS_FOR]-(me:Person)-[:HAS_SKILL]->(skill),
(company)<-[:WORKS_FOR]-(colleague)-[:HAS_SKILL]->(skill)
WHERE me.name = {name}
RETURN colleague.name AS name,
count(skill) AS score,
collect(skill.name) AS skills
ORDER BY score DESC
Search
nodes
labeled
‘Person’,
matching
on
‘name’
property
29. Create
Projec@on
of
Results
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
MATCH (company)<-[:WORKS_FOR]-(me:Person)-[:HAS_SKILL]->(skill),
(company)<-[:WORKS_FOR]-(colleague)-[:HAS_SKILL]->(skill)
WHERE me.name = {name}
RETURN colleague.name AS name,
count(skill) AS score,
collect(skill.name) AS skills
ORDER BY score DESC
34. From
User
Story
to
Model
and
Query
As
an
emp
loyee
I
want
to
k
now
who
i
n
the
co
has
similar
skills
to
me mpany
So
that
we
can
excha
nge
knowle
dge
MATCH (company)<-[:WORKS_FOR]-(me:Person)-[:HAS_SKILL]->(skill),
(company)<-[:WORKS_FOR]-(colleague)-[:HAS_SKILL]->(skill)
WHERE me.name = {name}
RETURN colleague.name AS name,
count(skill) AS score,
collect(skill.name) AS skills
ORDER BY score DESC
?
Which
people,
who
work
for
the
same
company
as
me,
have
similar
skills
to
me?
Person
WORKS_FOR
Company
Person
HAS_SKILL
Skill
(:Company)<-[:WORKS_FOR]-(:Person)-[:HAS_SKILL]->(:Skill)
36. Why
Test?
• Ensure
model
is
fit
for
queries
– Rapid
feedback
• Ensure
correctness
of
queries
• Document
your
understanding
of
your
domain
– Including
corner
cases
and
excep@ons
• Provide
a
regression
test
suite
– Allows
you
to
change
and
evolve
model
and
queries
37. Method
• Develop
queries,
or
classes
that
encapsulate
queries,
using
unit
tests
• Use
small,
well-‐understood
datasets
in
each
test
– Create
data
in
test
setup
– Test
dataset
expresses
your
understanding
of
(part
of)
the
domain
• Inject
in-‐memory
graph
database
(or
Cypher
engine)
into
object
under
test
• The
exact
strategy
you
use
depends
on
your
applica@on
architecture…
39. Applica@on
Architectures
• Embedded
– Host
in
Java
process
– Access
to
Java
APIs
• Server
• Server
with
Extensions
Applica@on
Java
APIs
40. Applica@on
Architectures
• Embedded
• Server
– HTTP/JSON
interface
– Server
wraps
embedded
instance
• Server
with
Extensions
Applica@on
REST
Client
Write
LB
REST
API
REST
API
Read
LB
REST
API
41. Applica@on
Architectures
• Embedded
• Server
• Server
with
Extensions
REST
API
– Execute
complex
logic
on
server
– Control
HTTP
request/response
format
Extensions
42. Embedded
Example
• Company
social
network
• Find
colleagues
with
similar
skills
• Encapsulate
query
in
a
ColleagueFinder
43. Unit
Test
Fixture
public class ColleagueFinderTest {
private GraphDatabaseService db;
private ColleagueFinder finder;
@Before
public void init() {
db = new TestGraphDatabaseFactory().newImpermanentDatabase();
ExampleGraph.populate( db );
finder = new ColleagueFinder( new ExecutionEngine( db ) );
}
@After
public void shutdown() {
db.shutdown();
}
}
44. Create
Database
public class ColleagueFinderTest {
private GraphDatabaseService db;
private ColleagueFinder finder;
@Before
public void init() {
db = new TestGraphDatabaseFactory().newImpermanentDatabase();
ExampleGraph.populate( db );
finder = new ColleagueFinder( new ExecutionEngine( db ) );
}
@After
public void shutdown() {
db.shutdown();
}
}
45. Populate
Graph
public class ColleagueFinderTest {
private GraphDatabaseService db;
private ColleagueFinder finder;
@Before
public void init() {
db = new TestGraphDatabaseFactory().newImpermanentDatabase();
ExampleGraph.populate( db );
finder = new ColleagueFinder( new ExecutionEngine( db ) );
}
@After
public void shutdown() {
db.shutdown();
}
}
46. Create
Object
Under
Test
public class ColleagueFinderTest {
private GraphDatabaseService db;
private ColleagueFinder finder;
@Before
public void init() {
db = new TestGraphDatabaseFactory().newImpermanentDatabase();
ExampleGraph.populate( db );
finder = new ColleagueFinder( new ExecutionEngine( db ) );
}
@After
public void shutdown() {
db.shutdown();
}
}
Inject
Execu@onEngine
47. ImpermanentGraphDatabase
• In-‐memory
• For
tes@ng
only,
not
produc@on!
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
75. ts gy
en lo
i m no
pl h
m ec
Co eo T
N
of
Graph
h
Databases
Thank
you
Twi$er:
@ianSrobinson
#neo4j
Neo4j
User
Group
30th
Oct
Skillsma$er
Ian Robinson,
Jim Webber & Emil Eifrem
github.com/iansrobinson/neo4j-‐good-‐prac@ces