2011-11-01 | 10:40 AM - 11:40 AM
Doctor Who is the world’s longest running science-fiction TV series. Battling daleks, cybermen and sontarans, and always accompanied by his trusted human companions, the last Timelord has saved earth from destruction more times than you’ve cursed Maven. Neo4j is the world’s leading open source graph database. Designed to interrogate densely connected data with lightning speed, it lets you traverse millions of nodes in a fraction of the time it takes to run a multi-join SQLquery. When these two meet, the result is an entertaining introduction to the complex history of a complex hero, and a rapid survey of the elegant APIs of a delightfully simple graph database. Armed only with a data store packed full of geeky Doctor Who facts, by the end of this session we’ll have you answering questions of the Doctor Who universe like a die-hard fan.
10. stole
companion
from
loves
loves
appeared
enemy
in
companion
appeared
in
appeared
in
enemy
enemy
appeared
appeared
A
Good
Man
in
in
Goes
to
War
Victory
of
the
Daleks
appeared
in
29. Iterable<Path>
path.startNode() path.endNode()
+tle:Power
of
species:Dalek
the
Daleks
props:Daleks
name:Dalek
7
type:skirt
name:Dalek
7
APPEARED_IN
USED_IN
MEMBER_OF
COMPOSED_OF
ORIGINAL_PROP
+tle:Power
of
species:Daleks
the
Daleks
props:Daleks
name:Dalek
7
type:shoulder
name:Dalek
7
APPEARED_IN
USED_IN
MEMBER_OF
COMPOSED_OF
ORIGINAL_PROP
+tle:Power
of
species:Daleks
the
Daleks
props:Daleks
name:Dalek
Six-‐5
type:skirt
name:Dalek
5
APPEARED_IN
USED_IN
MEMBER_OF
COMPOSED_OF
ORIGINAL_PROP
30. Cypher
• Declara+ve
graph
pa8ern
matching
language
– Humane
regular
expressions
for
graphs
• New
in
1.4
– Con+nuing,
rapid
feature
development
• Supports
queries
– Including
aggrega+on,
ordering
and
limits
– Muta+ng
opera+ons
coming
in
1.6
#neo4j
31. Cypher Query
start
daleks=node:species(species='Dalek')
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐
()<-‐[:MEMBER_OF]-‐()-‐[:COMPOSED_OF]-‐>
part-‐[:ORIGINAL_PROP]-‐>originalprop
return
originalprop.name,
part.type,
count(episode.Qtle)
order
by
count(episode.Qtle)
desc
limit
1
32. Index Lookup
start
daleks=node:species(species='Dalek')
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐
()<-‐[:MEMBER_OF]-‐()-‐[:COMPOSED_OF]-‐>
part-‐[:ORIGINAL_PROP]-‐>originalprop
return
originalprop.name,
part.type,
count(episode.Qtle)
order
by
count(episode.Qtle)
desc
limit
1
33. Match Nodes & Relationships
start
daleks=node:species(species='Dalek')
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐
()<-‐[:MEMBER_OF]-‐()-‐[:COMPOSED_OF]-‐>
part-‐[:ORIGINAL_PROP]-‐>originalprop
return
originalprop.name,
part.type,
count(episode.Qtle)
order
by
count(episode.Qtle)
desc
limit
1
34. match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐
()<-‐[:MEMBER_OF]-‐()-‐[:COMPOSED_OF]-‐>
part-‐[:ORIGINAL_PROP]-‐>originalprop
APPEARED_IN
daleks
episode
USED_IN
MEMBER_OF
COMPOSED_OF
ORIGINAL_PROP
part
originalprop
35. Return Values
start
daleks=node:species(species='Dalek')
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐
()<-‐[:MEMBER_OF]-‐()-‐[:COMPOSED_OF]-‐>
part-‐[:ORIGINAL_PROP]-‐>originalprop
return
originalprop.name,
part.type,
count(episode.Qtle)
order
by
count(episode.Qtle)
desc
limit
1
36. In Code
CypherParser
parser
=
new
CypherParser();
ExecuQonEngine
engine
=
new
ExecuQonEngine(universe.getDatabase());
String
cql
=
"start
daleks=node:species(species='Dalek')"
+
"
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐()<-‐[:MEMBER_OF]-‐()"
+
"-‐[:COMPOSED_OF]-‐>part-‐[:ORIGINAL_PROP]-‐>originalprop"
+
"
return
originalprop.name,
part.type,
count(episode.Qtle)"
+
"
order
by
count(episode.Qtle)
desc
limit
1";
Query
query
=
parser.parse(cql);
ExecuQonResult
result
=
engine.execute(query);
String
originalProp
=
result.javaColumnAs("originalprop.name").next().toString();
String
part
=
result.javaColumnAs("part.type").next().toString();
int
episodeCount
=
(Integer)
result.javaColumnAs("count(episode.Qtle)").next();
37. Setup
CypherParser
parser
=
new
CypherParser();
ExecuQonEngine
engine
=
new
ExecuQonEngine(universe.getDatabase());
String
cql
=
"start
daleks=node:species(species='Dalek')"
+
"
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐()<-‐[:MEMBER_OF]-‐()"
+
"-‐[:COMPOSED_OF]-‐>part-‐[:ORIGINAL_PROP]-‐>originalprop"
+
"
return
originalprop.name,
part.type,
count(episode.Qtle)"
+
"
order
by
count(episode.Qtle)
desc
limit
1";
Query
query
=
parser.parse(cql);
ExecuQonResult
result
=
engine.execute(query);
String
originalProp
=
result.javaColumnAs("originalprop.name").next().toString();
String
part
=
result.javaColumnAs("part.type").next().toString();
int
episodeCount
=
(Integer)
result.javaColumnAs("count(episode.Qtle)").next();
38. Parse & Execute
CypherParser
parser
=
new
CypherParser();
ExecuQonEngine
engine
=
new
ExecuQonEngine(universe.getDatabase());
String
cql
=
"start
daleks=node:species(species='Dalek')"
+
"
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐()<-‐[:MEMBER_OF]-‐()"
+
"-‐[:COMPOSED_OF]-‐>part-‐[:ORIGINAL_PROP]-‐>originalprop"
+
"
return
originalprop.name,
part.type,
count(episode.Qtle)"
+
"
order
by
count(episode.Qtle)
desc
limit
1";
Query
query
=
parser.parse(cql);
ExecuQonResult
result
=
engine.execute(query);
String
originalProp
=
result.javaColumnAs("originalprop.name").next().toString();
String
part
=
result.javaColumnAs("part.type").next().toString();
int
episodeCount
=
(Integer)
result.javaColumnAs("count(episode.Qtle)").next();
39. Results
CypherParser
parser
=
new
CypherParser();
ExecuQonEngine
engine
=
new
ExecuQonEngine(universe.getDatabase());
String
cql
=
"start
daleks=node:species(species='Dalek')"
+
"
match
daleks-‐[:APPEARED_IN]-‐>episode<-‐[:USED_IN]-‐()<-‐[:MEMBER_OF]-‐()"
+
"-‐[:COMPOSED_OF]-‐>part-‐[:ORIGINAL_PROP]-‐>originalprop"
+
"
return
originalprop.name,
part.type,
count(episode.Qtle)"
+
"
order
by
count(episode.Qtle)
desc
limit
1";
Query
query
=
parser.parse(cql);
ExecuQonResult
result
=
engine.execute(query);
String
originalProp
=
result.javaColumnAs("originalprop.name").next().toString();
String
part
=
result.javaColumnAs("part.type").next().toString();
int
episodeCount
=
(Integer)
result.javaColumnAs("count(episode.Qtle)").next();