Introduc)on	
  to	
  graph	
  databases,	
  Neo4j	
  
and	
  Spring	
  Data	
  
	
  
Aleksander	
  M.	
  Stensby	
  
Monokkel	
  A/S	
  
•  Aleksander	
  M.	
  Stensby	
  
•  CEO	
  in	
  Monokkel	
  AS	
  
•  Previously	
  COO	
  in	
  Integrasco	
  AS	
  
•  Working	
  with	
  search	
  and	
  data	
  analysis	
  since	
  2004	
  
www.monokkel.io	
  
•  Daglig	
  leder	
  i	
  Monokkel	
  AS	
  
•  Tidligere	
  COO	
  i	
  Integrasco	
  AS	
  
•  Persistering,	
  Prosessering	
  og	
  Presentasjon	
  av	
  data	
  
Persistence	
  –	
  Processing	
  –	
  PresentaHon	
  
Agenda	
  
•  Intro	
  to	
  graph	
  databases	
  and	
  modelling	
  
	
  
•  Neo4j	
  and	
  Cypher	
  
	
  
•  SpringData	
  Neo4j	
  
RelaHonal	
  databases…	
  
…when	
  it	
  comes	
  to	
  relaHons	
  
RelaHonal	
  databases	
  are	
  awesome	
  
when	
  it	
  comes	
  to	
  aggregaHon	
  of	
  data,	
  
schema	
  mapping	
  and	
  tabular	
  data!	
  
BUT	
  
We	
  have	
  a	
  tendency	
  to	
  force	
  	
  
_all_	
  	
  
our	
  problems	
  into	
  our	
  relaHonal	
  
databases!	
  
Join-­‐hell..	
  
Recursion...	
  
Null-­‐checks...	
  
Polyglot	
  persistence	
  
NoSQL	
  
Not	
  only	
  SQL	
  
NoSQL	
  
•  Key-­‐value	
  stores	
  
– Amazon	
  Dynamo	
  
– Ex:	
  Voldemort,...	
  
•  BigTable	
  clones	
  
– Google’s	
  BigTable	
  
– Ex:	
  Hbase,	
  ...	
  
•  Document	
  databases	
  
– Lotus	
  Notes	
  
– Ex:	
  MongoDB,	
  CouchDB	
  
NoSQL	
  
•  Graph	
  databases	
  
– Euler	
  and	
  graph	
  theory	
  
– Ex:	
  Neo4j,	
  VertexDB,	
  AllegroGraph,	
  
Giraphe,	
  OrientDB,	
  etc...	
  
NoSQL	
  Size	
  
Complexity	
  
Graphs	
  
Document	
  
BigTable	
  
KV	
  
NoSQL	
  Size	
  
Complexity	
  
Graphs	
  
Document	
  
BigTable	
  
KV	
  
90%	
  
Billions	
  of	
  nodes	
  and	
  rela)onships	
  
enough	
  buzzwords…	
  
Friends	
  of	
  friends...	
  
Person	
  
ID	
  
Name	
  
Friends	
  
PersonID	
  
FriendID	
  
Person	
  
ID	
  
Name	
  
Friends	
  
PersonID	
  
FriendID	
  
«Aleks»’s	
  friends	
  
SELECT	
  p1.Person	
  
FROM	
  Person	
  p1	
  JOIN	
  Friends	
  
	
  ON	
  Friends.FriendID	
  =	
  p1.ID	
  
JOIN	
  Person	
  p2	
  
	
  ON	
  Friends.PersonID	
  =	
  p2.ID	
  
WHERE	
  p2.Name=	
  'Aleks'	
  
Person	
  
ID	
  
Name	
  
Friends	
  
PersonID	
  
FriendID	
  
Friends	
  with	
  «Aleks»	
  
SELECT	
  p1.Person	
  
FROM	
  Person	
  p1	
  JOIN	
  Friends	
  
	
  ON	
  Friends.PersonID	
  =	
  p1.ID	
  
JOIN	
  Person	
  p2	
  
	
  ON	
  Friends.FriendID	
  =	
  p2.ID	
  
WHERE	
  p2.Name	
  =	
  'Aleks'	
  
Person	
  
ID	
  
Name	
  
Friends	
  
PersonID	
  
FriendID	
  
«Aleks»’s	
  friends’	
  friends?	
  
SELECT	
  p1.Person	
  AS	
  PERSON,	
  p2.Person	
  AS	
  FRIEND_OF_FRIEND	
  
FROM	
  Friends	
  v1	
  JOIN	
  Person	
  p1	
  
	
  ON	
  v1.PersonID	
  =	
  p1.ID	
  
JOIN	
  Friends	
  v2	
  
	
  ON	
  v2.FriendID	
  =	
  v1.FriendID	
  
JOIN	
  Person	
  p2	
  
	
  ON	
  v2.FriendID	
  =	
  p2.	
  ID	
  
WHERE	
  p1.Name	
  =	
  'Aleks‘	
  AND	
  v2.FriendID	
  <>	
  p1.ID	
  
Source:	
  Neo4j	
  in	
  AcHon
1,000,000	
  persons	
  
Depth	
   RDBMS	
   Neo4j	
   Records	
  
2	
   0.016	
   0.01	
   ~	
  2500	
  
3	
   30.267	
   0.168	
   ~	
  110,000	
  
4	
   1543.505	
   1.359	
   ~	
  600,000	
  
5	
   DNF	
   2.132	
   ~	
  800,000	
  
A	
  graph	
  database...	
  
•  uses	
  graph	
  structures	
  with	
  
– Nodes	
  
– RelaHonships	
  
– Apributes	
  
	
  
•  to	
  store	
  informaHon!	
  
•  Exellent	
  for	
  relaHonships	
  –	
  but	
  not	
  necessarily	
  
best	
  at	
  aggregaHng	
  data	
  
Graph	
  databases	
  and	
  neo4j	
  
•  Visual	
  –	
  Schema	
  less!	
  	
  
•  Doubly-­‐linked-­‐lists	
  
– each	
  node	
  has	
  a	
  list	
  of	
  incoming	
  and	
  outgoing	
  
relaWonships	
  
	
  
•  Direct	
  lookup	
  =	
  O(1)	
  
A	
  graph	
  stores	
  data	
  in	
  nodes	
  
ALEKS	
   TARJEI	
  
Nodes	
  are	
  connected	
  by	
  relaWonships	
  
FRIENDS_WITH	
  
ALEKS	
   TARJEI	
  
Nodes	
  have	
  aributes	
  
ALEKS	
   TARJEI	
  
Age:	
  29	
  
First	
  Name:	
  Aleksander	
  
Last	
  Name:	
  Stensby	
  
	
  
Age:	
  30	
  
First	
  Name:	
  Tarjei	
  
Last	
  Name:	
  Romtveit	
  
	
  
FRIENDS_WITH	
  
RelaWonships	
  can	
  also	
  have	
  aributes	
  
ALEKS	
   TARJEI	
  
Age:	
  29	
  
First	
  Name:	
  Aleksander	
  
Last	
  Name:	
  Stensby	
  
	
  
Age:	
  30	
  
First	
  Name:	
  Tarjei	
  
Last	
  Name:	
  Romtveit	
  
	
  
FRIENDS_WITH	
  
Since:	
  01.01.2004	
  
RelaWonships	
  can	
  be	
  bi-­‐direcHonal	
  
ALEKS	
   TARJEI	
  
Age:	
  29	
  
First	
  Name:	
  Aleksander	
  
Last	
  Name:	
  Stensby	
  
	
  
Age:	
  30	
  
First	
  Name:	
  Tarjei	
  
Last	
  Name:	
  Romtveit	
  
	
  
FRIENDS_WITH	
  
Since:	
  01.01.2004	
  
FRIENDS_WITH	
  
Since:	
  01.01.2004	
  
ALEKS	
   TARJEI	
  
Age:	
  29	
  
First	
  Name:	
  Aleksander	
  
Last	
  Name:	
  Stensby	
  
	
  
Age:	
  30	
  
First	
  Name:	
  Tarjei	
  
Last	
  Name:	
  Romtveit	
  
	
  
FRIENDS_WITH	
  
Since:	
  01.01.2004	
  
ALEKS	
   TARJEI	
  
Age:	
  29	
  
First	
  Name:	
  Aleksander	
  
Last	
  Name:	
  Stensby	
  
Type:	
  Person	
  
	
  
Age:	
  30	
  
First	
  Name:	
  Tarjei	
  
Last	
  Name:	
  Romtveit	
  
Type:	
  Person	
  
	
  
FRIENDS_WITH	
  
Since:	
  01.01.2004	
  
different	
  types	
  of	
  nodes	
  
Person	
   Person	
  
Sport	
  
Programming	
  language	
  
Drink	
  
Person	
  
Some	
  use	
  cases	
  
•  Social	
  Media	
  
•  RecommendaHons	
  
•  Geo	
  rouHng	
  and	
  logisHcs	
  
•  Access	
  management	
  
•  Network	
  management	
  
•  Finance	
  /	
  Fraud	
  
Neo4j	
  –	
  [IS_A]	
  -­‐>	
  Property	
  Graph	
  
Neo4j	
  2.2.x	
  
•  Currently	
  early	
  access	
  milestone	
  4	
  
•  New	
  page	
  cache	
  -­‐>	
  high	
  concurrency	
  
	
  
•  TransacHonal	
  and	
  batch	
  write	
  performance	
  
•  Cost-­‐Based	
  OpHmizer	
  for	
  Cypher	
  
(node)	
  –	
  [relaHonship]	
  -­‐>	
  (node)	
  
(Aleks)	
  –	
  [FRIENDS_WITH]	
  -­‐>	
  (Tarjei)	
  
Cypher	
  
"Make	
  the	
  simple	
  things	
  simple,	
  and	
  the	
  complex	
  things	
  possible"	
  
Intro	
  to	
  Cypher	
  
•  START	
  
•  MATCH	
  
•  WHERE	
  
•  RETURN	
  
•  CREATE	
  
•  DELETE	
  
•  SET	
  
•  FOREACH	
  
•  WITH	
  
MATCH	
  <papern>	
  	
  
WHERE	
  
RETURN	
  	
  
Describe	
  what	
  you	
  want	
  to	
  retrieve	
  
with	
  PATTERNS	
  
(a)-­‐[r]-­‐>(b)	
  
(Aleks)	
  –	
  [FRIENDS_WITH]	
  -­‐>	
  (Tarjei)	
  
Path	
  depth	
  
(a)-­‐[*]-­‐>(b)	
  
	
  
	
  
START	
  
START	
  n=node(1)	
  
RETURN	
  n	
  
MATCH	
  
MATCH	
  (movie:Movie)	
  
RETURN	
  movie	
  
WHERE	
  
MATCH	
  movie	
  
WHERE	
  move.Htle	
  =	
  ‘Blade	
  Runner'	
  
RETURN	
  movie	
  
START	
  a=node(*)	
  
MATCH	
  (a:Person)	
  
WHERE	
  a.name='Danny	
  DeVito'	
  
RETURN	
  a	
  
START	
  a=node(*)	
  
MATCH	
  (a:Person)	
  
WHERE	
  a.name='Danny	
  DeVito'	
  
RETURN	
  a	
  
START	
  a=node(*)	
  
MATCH	
  (a:Person	
  {name:	
  'Danny	
  DeVito'}	
  )	
  
WHERE	
  a.name='Danny	
  DeVito'	
  
RETURN	
  a	
  
Neo4j	
  2.0.1	
  
Friend	
  of	
  friend...	
  
MATCH	
  (aleks)-­‐[r:KNOWS]-­‐()-­‐[r2:KNOWS]	
  -­‐>(friend_of_friend)	
  
WHERE	
  aleks.firstName=	
  'Aleks'	
  
RETURN	
  friend_of_friend.firstName	
  
Friend	
  of	
  friend...	
  
MATCH	
  (aleks)-­‐[:KNOWS*2..2]-­‐>(friend_of_friend)	
  
WHERE	
  aleks.firstName=	
  'Aleks'	
  
AND	
  NOT	
  (aleks)-­‐[:KNOWS]-­‐>(friend_of_friend)	
  
RETURN	
  friend_of_friend.firstName	
  
hpp://docs.neo4j.org/refcard/2.1.7/	
  
 
	
  
	
  
	
  
	
  
DEMO	
  
	
  
And	
  a	
  whole	
  lot	
  more…	
  
•  Traversals	
  to	
  navigate	
  the	
  graph	
  
•  Traversals	
  idenHfy	
  paths	
  
•  Paths	
  order	
  nodes	
  
•  Cypher	
  parameters	
  
•  Indexes	
  
•  Neo4j	
  embedded,	
  Neo4j	
  REST	
  
•  Neo4j	
  2.x	
  –	
  Labels	
  and	
  automaWc	
  indexes	
  
•  Gremlin	
  (procedural)	
  –	
  Cypher	
  (declaraHve)	
  
•  Enterprise	
  (mulH-­‐instance	
  cluster,	
  online	
  backup)	
  
•  Neo4j	
  SpaWal	
  
Language	
  drivers	
  
Contrib	
  
Intro	
  to	
  SpringData	
  Neo4j	
  
•  SpringData	
  
•  Repositories	
  
•  Quick	
  example	
  
<dependencies>	
  
	
  	
  	
  	
  <dependency>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <groupId>org.springframework.data</groupId>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <arHfactId>spring-­‐data-­‐neo4j</arHfactId>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <version>3.2.2.RELEASE</version>	
  
	
  	
  	
  	
  </dependency>	
  
</dependencies>	
  
neo4j 	
   	
   	
  2.1.7	
  
spring-­‐data-­‐neo4j 	
   	
  3.2.2	
  
spring 	
   	
   	
  4.1.4	
  
SpringData	
  Neo4j	
  Config	
  
@Configuration	
  
@EnableNeo4jRepositories("no.stensby.javabin.neo.repositories")	
  
public	
  class	
  Config	
  extends	
  Neo4jConfiguration	
  {	
  
}	
  
@Autowired	
  
protected	
  Neo4jTemplate	
  template;	
  
SpringData	
  Neo4j	
  Config	
  
@Configuration	
  
@EnableNeo4jRepositories("no.stensby.javabin.neo.repositories")	
  
public	
  class	
  Config	
  extends	
  Neo4jConfiguration	
  {	
  
	
  
	
  public	
  Config	
  (){	
  
	
  	
  	
  	
  	
  	
  	
  	
  setBasePackage("no.stensby.javabin.neo.domain");	
  
	
  	
  	
  	
  }	
  
	
  
}	
  
@Autowired	
  
protected	
  Neo4jTemplate	
  template;	
  
SpringData	
  Neo4j	
  Config	
  
@Bean	
  
GraphDatabaseService	
  graphDatabaseService()	
  {	
  
return	
  new	
  GraphDatabaseFactory().newEmbeddedDatabase("tmp/neo4j");	
  
}	
  
Embedded:	
  
REST:	
  	
  
@Bean	
  
GraphDatabaseService	
  graphDatabaseService()	
  {	
  
return	
  new	
  SpringRestGraphDatabase("http://localhost:7474/db/data");	
  
}	
  
@Bean(destroyMethod	
  =	
  "shutdown")	
  
@Scope(SCOPE_PROTOTYPE)	
  
public	
  GraphDatabaseService	
  graphDatabaseService()	
  {	
  
return	
  new	
  TestGraphDatabaseFactory().newImpermanentDatabase();	
  
}	
  
TEST:	
  	
  
SpringData	
  Neo4j	
  -­‐	
  Domain	
  
@NodeEntity	
  
public	
  class	
  Person	
  {	
  
@GraphId	
  
public	
  Long	
  nodeId;	
  
	
  
@Indexed(unique	
  =	
  true)	
  
public	
  int	
  id;	
  
	
  
public	
  String	
  firstName;	
  
public	
  String	
  lastName;	
  
}	
  
1-­‐1	
  relaHonships	
  
@NodeEntity	
  
public	
  class	
  Address	
  {	
  
	
  
private	
  Country	
  country;	
  
	
  
...	
  
}	
  
1-­‐1	
  relaHonships	
  
@NodeEntity	
  
public	
  class	
  Address	
  {	
  
	
  
@Fetch	
  
private	
  Country	
  country;	
  
	
  
...	
  
}	
  
1-­‐m	
  relaHonships	
  -­‐	
  @RelatedTo	
  
@RelatedTo(type	
  =	
  "ADDRESS")	
  
private	
  Set<Address>	
  addresses	
  =	
  new	
  HashSet<Address>();	
  
@RelatedTo	
  
private	
  Set<Person>	
  venner	
  =	
  new	
  HashSet<Person>	
  ();	
  
m-­‐m	
  relaHonships	
  -­‐	
  @RelatedToVia	
  
@Fetch	
  
@RelatedToVia	
  (type	
  =	
  "ACTS_IN")	
  
Set<Role>	
  roles	
  =	
  new	
  
HashSet<Role>();	
  
@Fetch	
  
@RelatedToVia(type	
  =	
  "ACTS_IN",	
  direction	
  =	
  Direction.INCOMING)	
  	
  
Set<Role>	
  cast	
  =	
  new	
  HashSet<Role>();	
  
Actor	
  Movie	
  
@RelationshipEntity(type	
  =	
  "ACTS_IN")	
  
public	
  class	
  Role	
  {	
  
@GraphId	
  
Long	
  nodeId;	
  
@StartNode	
  
Actor	
  actor;	
  
@EndNode	
  
Movie	
  movie;	
  
Role	
  
SpringData	
  Neo4j	
  -­‐	
  Repositories	
  
GraphRepository<Person>	
  personRepository	
  =	
  template.repositoryFor(Person.class);	
  
@Autowired	
  
Neo4jTemplate	
  template;	
  
SpringData	
  Neo4j	
  -­‐	
  Repositories	
  
public	
  interface	
  PersonRepository	
  extends	
  GraphRepository<Person>{}	
  
@Autowired	
  
PersonRepository	
  repository;	
  
SpringData	
  Neo4j	
  -­‐	
  Repositories	
  
public	
  interface	
  PersonRepository	
  extends	
  GraphRepository<Person>{	
  
	
  
	
  
List<Person>	
  findByFirstName(String	
  firstName);	
  
	
  
}	
  
SpringData	
  Neo4j	
  -­‐	
  Repositories	
  
public	
  interface	
  PersonRepository	
  extends	
  GraphRepository<Person>{	
  
	
  
	
  
List<Person>	
  findByFirstName(String	
  firstName);	
  
	
  
@Query("MATCH	
  (p:Person{firstName:{0}})	
  RETURN	
  p")	
  	
  
List<Person>	
  getPersonWithFirstName	
  (String	
  firstName);	
  
	
  
}	
  
SpringData	
  Neo4j	
  -­‐	
  Repositories	
  
public	
  interface	
  PersonRepository	
  extends	
  GraphRepository<Person>{	
  
	
  
	
  
List<Person>	
  findByFirstName(String	
  firstName);	
  
	
  
@Query("MATCH	
  (p:Person{firstName:{0}})	
  RETURN	
  p")	
  	
  
List<Person>	
  getPersonWithFirstName	
  (String	
  firstName);	
  
	
  
	
  
@Query(	
  "MATCH	
  (p:Person{firstName:{0}})-­‐[:knows]-­‐>friends	
  "	
  +	
  
	
  "	
  RETURN	
  friends")	
  	
  
Iterable<Person>	
  findFriendsOfPerson(String	
  firstName);	
  
	
  
	
  
}	
  
Lessons	
  Learned	
  
•  Be	
  careful	
  with	
  versions	
  and	
  upgrading	
  …	
  
–  Neo	
  1.9.x	
  -­‐>	
  Neo	
  2.x	
  =	
  lots	
  of	
  problems…	
  
–  Lots	
  of	
  breaking	
  changes…	
  
–  Spring	
  Data	
  Neo4j	
  !=	
  Neo4j	
  
	
  
•  Nodes	
  are	
  “first-­‐class”	
  ciHzens	
  in	
  the	
  graph	
  
–  Hyperedges	
  are	
  not	
  supported	
  -­‐>	
  use	
  “event	
  nodes”	
  
	
  
•  AggregaHons	
  are	
  expensive	
  –	
  caching	
  stats	
  on	
  nodes!	
  
•  Unique	
  and	
  expressive	
  relaHonship	
  types	
  
Pi•alls	
  
•  Don’t	
  use	
  the	
  graphid	
  as	
  your	
  ID	
  
•  IniHalize	
  Set	
  
•  Use	
  @Fetch	
  with	
  care	
  
•  Use	
  standard	
  gepers/sepers	
  
•  Be	
  careful	
  with	
  String	
  escaping	
  
InspiraHon	
  
•  Single	
  Malt	
  Scotch	
  Whisky	
  
hpp://gist.neo4j.org/?8139605	
  
	
  
•  Chess	
  Games	
  and	
  PosiWons	
  
hpp://gist.neo4j.org/?6506717	
  
	
  
•  Movie	
  RecommendaWons	
  
hpp://gist.neo4j.org/?8173017	
  
•  Food	
  Recipes	
  RecommendaWon	
  
hpp://gist.neo4j.org/?8731452	
  

Introduction to graph databases, Neo4j and Spring Data - English 2015 Edition

  • 1.
    Introduc)on  to  graph  databases,  Neo4j   and  Spring  Data     Aleksander  M.  Stensby   Monokkel  A/S  
  • 2.
    •  Aleksander  M.  Stensby   •  CEO  in  Monokkel  AS   •  Previously  COO  in  Integrasco  AS   •  Working  with  search  and  data  analysis  since  2004   www.monokkel.io  
  • 3.
    •  Daglig  leder  i  Monokkel  AS   •  Tidligere  COO  i  Integrasco  AS   •  Persistering,  Prosessering  og  Presentasjon  av  data   Persistence  –  Processing  –  PresentaHon  
  • 4.
    Agenda   •  Intro  to  graph  databases  and  modelling     •  Neo4j  and  Cypher     •  SpringData  Neo4j  
  • 5.
  • 6.
    …when  it  comes  to  relaHons  
  • 7.
    RelaHonal  databases  are  awesome   when  it  comes  to  aggregaHon  of  data,   schema  mapping  and  tabular  data!  
  • 8.
  • 9.
    We  have  a  tendency  to  force     _all_     our  problems  into  our  relaHonal   databases!  
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
    NoSQL   •  Key-­‐value  stores   – Amazon  Dynamo   – Ex:  Voldemort,...   •  BigTable  clones   – Google’s  BigTable   – Ex:  Hbase,  ...   •  Document  databases   – Lotus  Notes   – Ex:  MongoDB,  CouchDB  
  • 15.
    NoSQL   •  Graph  databases   – Euler  and  graph  theory   – Ex:  Neo4j,  VertexDB,  AllegroGraph,   Giraphe,  OrientDB,  etc...  
  • 16.
    NoSQL  Size   Complexity   Graphs   Document   BigTable   KV  
  • 17.
    NoSQL  Size   Complexity   Graphs   Document   BigTable   KV   90%   Billions  of  nodes  and  rela)onships  
  • 18.
  • 19.
  • 20.
    Person   ID   Name   Friends   PersonID   FriendID  
  • 21.
    Person   ID   Name   Friends   PersonID   FriendID   «Aleks»’s  friends   SELECT  p1.Person   FROM  Person  p1  JOIN  Friends    ON  Friends.FriendID  =  p1.ID   JOIN  Person  p2    ON  Friends.PersonID  =  p2.ID   WHERE  p2.Name=  'Aleks'  
  • 22.
    Person   ID   Name   Friends   PersonID   FriendID   Friends  with  «Aleks»   SELECT  p1.Person   FROM  Person  p1  JOIN  Friends    ON  Friends.PersonID  =  p1.ID   JOIN  Person  p2    ON  Friends.FriendID  =  p2.ID   WHERE  p2.Name  =  'Aleks'  
  • 23.
    Person   ID   Name   Friends   PersonID   FriendID   «Aleks»’s  friends’  friends?   SELECT  p1.Person  AS  PERSON,  p2.Person  AS  FRIEND_OF_FRIEND   FROM  Friends  v1  JOIN  Person  p1    ON  v1.PersonID  =  p1.ID   JOIN  Friends  v2    ON  v2.FriendID  =  v1.FriendID   JOIN  Person  p2    ON  v2.FriendID  =  p2.  ID   WHERE  p1.Name  =  'Aleks‘  AND  v2.FriendID  <>  p1.ID  
  • 24.
    Source:  Neo4j  in  AcHon 1,000,000  persons   Depth   RDBMS   Neo4j   Records   2   0.016   0.01   ~  2500   3   30.267   0.168   ~  110,000   4   1543.505   1.359   ~  600,000   5   DNF   2.132   ~  800,000  
  • 26.
    A  graph  database...   •  uses  graph  structures  with   – Nodes   – RelaHonships   – Apributes     •  to  store  informaHon!   •  Exellent  for  relaHonships  –  but  not  necessarily   best  at  aggregaHng  data  
  • 27.
    Graph  databases  and  neo4j   •  Visual  –  Schema  less!     •  Doubly-­‐linked-­‐lists   – each  node  has  a  list  of  incoming  and  outgoing   relaWonships     •  Direct  lookup  =  O(1)  
  • 28.
    A  graph  stores  data  in  nodes   ALEKS   TARJEI  
  • 29.
    Nodes  are  connected  by  relaWonships   FRIENDS_WITH   ALEKS   TARJEI  
  • 30.
    Nodes  have  aributes   ALEKS   TARJEI   Age:  29   First  Name:  Aleksander   Last  Name:  Stensby     Age:  30   First  Name:  Tarjei   Last  Name:  Romtveit     FRIENDS_WITH  
  • 31.
    RelaWonships  can  also  have  aributes   ALEKS   TARJEI   Age:  29   First  Name:  Aleksander   Last  Name:  Stensby     Age:  30   First  Name:  Tarjei   Last  Name:  Romtveit     FRIENDS_WITH   Since:  01.01.2004  
  • 32.
    RelaWonships  can  be  bi-­‐direcHonal   ALEKS   TARJEI   Age:  29   First  Name:  Aleksander   Last  Name:  Stensby     Age:  30   First  Name:  Tarjei   Last  Name:  Romtveit     FRIENDS_WITH   Since:  01.01.2004   FRIENDS_WITH   Since:  01.01.2004  
  • 33.
    ALEKS   TARJEI   Age:  29   First  Name:  Aleksander   Last  Name:  Stensby     Age:  30   First  Name:  Tarjei   Last  Name:  Romtveit     FRIENDS_WITH   Since:  01.01.2004  
  • 34.
    ALEKS   TARJEI   Age:  29   First  Name:  Aleksander   Last  Name:  Stensby   Type:  Person     Age:  30   First  Name:  Tarjei   Last  Name:  Romtveit   Type:  Person     FRIENDS_WITH   Since:  01.01.2004   different  types  of  nodes  
  • 35.
    Person   Person   Sport   Programming  language   Drink   Person  
  • 36.
    Some  use  cases   •  Social  Media   •  RecommendaHons   •  Geo  rouHng  and  logisHcs   •  Access  management   •  Network  management   •  Finance  /  Fraud  
  • 37.
    Neo4j  –  [IS_A]  -­‐>  Property  Graph  
  • 38.
    Neo4j  2.2.x   • Currently  early  access  milestone  4   •  New  page  cache  -­‐>  high  concurrency     •  TransacHonal  and  batch  write  performance   •  Cost-­‐Based  OpHmizer  for  Cypher  
  • 40.
    (node)  –  [relaHonship]  -­‐>  (node)  
  • 41.
    (Aleks)  –  [FRIENDS_WITH]  -­‐>  (Tarjei)  
  • 42.
    Cypher   "Make  the  simple  things  simple,  and  the  complex  things  possible"  
  • 43.
    Intro  to  Cypher   •  START   •  MATCH   •  WHERE   •  RETURN   •  CREATE   •  DELETE   •  SET   •  FOREACH   •  WITH  
  • 44.
    MATCH  <papern>     WHERE   RETURN    
  • 45.
    Describe  what  you  want  to  retrieve   with  PATTERNS   (a)-­‐[r]-­‐>(b)  
  • 46.
    (Aleks)  –  [FRIENDS_WITH]  -­‐>  (Tarjei)  
  • 47.
  • 48.
  • 49.
    MATCH   MATCH  (movie:Movie)   RETURN  movie  
  • 50.
    WHERE   MATCH  movie   WHERE  move.Htle  =  ‘Blade  Runner'   RETURN  movie  
  • 51.
    START  a=node(*)   MATCH  (a:Person)   WHERE  a.name='Danny  DeVito'   RETURN  a  
  • 52.
    START  a=node(*)   MATCH  (a:Person)   WHERE  a.name='Danny  DeVito'   RETURN  a  
  • 53.
    START  a=node(*)   MATCH  (a:Person  {name:  'Danny  DeVito'}  )   WHERE  a.name='Danny  DeVito'   RETURN  a   Neo4j  2.0.1  
  • 54.
    Friend  of  friend...   MATCH  (aleks)-­‐[r:KNOWS]-­‐()-­‐[r2:KNOWS]  -­‐>(friend_of_friend)   WHERE  aleks.firstName=  'Aleks'   RETURN  friend_of_friend.firstName  
  • 55.
    Friend  of  friend...   MATCH  (aleks)-­‐[:KNOWS*2..2]-­‐>(friend_of_friend)   WHERE  aleks.firstName=  'Aleks'   AND  NOT  (aleks)-­‐[:KNOWS]-­‐>(friend_of_friend)   RETURN  friend_of_friend.firstName  
  • 56.
  • 57.
              DEMO    
  • 58.
    And  a  whole  lot  more…   •  Traversals  to  navigate  the  graph   •  Traversals  idenHfy  paths   •  Paths  order  nodes   •  Cypher  parameters   •  Indexes   •  Neo4j  embedded,  Neo4j  REST   •  Neo4j  2.x  –  Labels  and  automaWc  indexes   •  Gremlin  (procedural)  –  Cypher  (declaraHve)   •  Enterprise  (mulH-­‐instance  cluster,  online  backup)   •  Neo4j  SpaWal  
  • 59.
  • 60.
  • 62.
    Intro  to  SpringData  Neo4j   •  SpringData   •  Repositories   •  Quick  example   <dependencies>          <dependency>                  <groupId>org.springframework.data</groupId>                  <arHfactId>spring-­‐data-­‐neo4j</arHfactId>                  <version>3.2.2.RELEASE</version>          </dependency>   </dependencies>   neo4j      2.1.7   spring-­‐data-­‐neo4j    3.2.2   spring      4.1.4  
  • 63.
    SpringData  Neo4j  Config   @Configuration   @EnableNeo4jRepositories("no.stensby.javabin.neo.repositories")   public  class  Config  extends  Neo4jConfiguration  {   }   @Autowired   protected  Neo4jTemplate  template;  
  • 64.
    SpringData  Neo4j  Config   @Configuration   @EnableNeo4jRepositories("no.stensby.javabin.neo.repositories")   public  class  Config  extends  Neo4jConfiguration  {      public  Config  (){                  setBasePackage("no.stensby.javabin.neo.domain");          }     }   @Autowired   protected  Neo4jTemplate  template;  
  • 65.
    SpringData  Neo4j  Config   @Bean   GraphDatabaseService  graphDatabaseService()  {   return  new  GraphDatabaseFactory().newEmbeddedDatabase("tmp/neo4j");   }   Embedded:   REST:     @Bean   GraphDatabaseService  graphDatabaseService()  {   return  new  SpringRestGraphDatabase("http://localhost:7474/db/data");   }   @Bean(destroyMethod  =  "shutdown")   @Scope(SCOPE_PROTOTYPE)   public  GraphDatabaseService  graphDatabaseService()  {   return  new  TestGraphDatabaseFactory().newImpermanentDatabase();   }   TEST:    
  • 66.
    SpringData  Neo4j  -­‐  Domain   @NodeEntity   public  class  Person  {   @GraphId   public  Long  nodeId;     @Indexed(unique  =  true)   public  int  id;     public  String  firstName;   public  String  lastName;   }  
  • 67.
    1-­‐1  relaHonships   @NodeEntity   public  class  Address  {     private  Country  country;     ...   }  
  • 68.
    1-­‐1  relaHonships   @NodeEntity   public  class  Address  {     @Fetch   private  Country  country;     ...   }  
  • 69.
    1-­‐m  relaHonships  -­‐  @RelatedTo   @RelatedTo(type  =  "ADDRESS")   private  Set<Address>  addresses  =  new  HashSet<Address>();   @RelatedTo   private  Set<Person>  venner  =  new  HashSet<Person>  ();  
  • 70.
    m-­‐m  relaHonships  -­‐  @RelatedToVia   @Fetch   @RelatedToVia  (type  =  "ACTS_IN")   Set<Role>  roles  =  new   HashSet<Role>();   @Fetch   @RelatedToVia(type  =  "ACTS_IN",  direction  =  Direction.INCOMING)     Set<Role>  cast  =  new  HashSet<Role>();   Actor  Movie   @RelationshipEntity(type  =  "ACTS_IN")   public  class  Role  {   @GraphId   Long  nodeId;   @StartNode   Actor  actor;   @EndNode   Movie  movie;   Role  
  • 71.
    SpringData  Neo4j  -­‐  Repositories   GraphRepository<Person>  personRepository  =  template.repositoryFor(Person.class);   @Autowired   Neo4jTemplate  template;  
  • 72.
    SpringData  Neo4j  -­‐  Repositories   public  interface  PersonRepository  extends  GraphRepository<Person>{}   @Autowired   PersonRepository  repository;  
  • 73.
    SpringData  Neo4j  -­‐  Repositories   public  interface  PersonRepository  extends  GraphRepository<Person>{       List<Person>  findByFirstName(String  firstName);     }  
  • 74.
    SpringData  Neo4j  -­‐  Repositories   public  interface  PersonRepository  extends  GraphRepository<Person>{       List<Person>  findByFirstName(String  firstName);     @Query("MATCH  (p:Person{firstName:{0}})  RETURN  p")     List<Person>  getPersonWithFirstName  (String  firstName);     }  
  • 75.
    SpringData  Neo4j  -­‐  Repositories   public  interface  PersonRepository  extends  GraphRepository<Person>{       List<Person>  findByFirstName(String  firstName);     @Query("MATCH  (p:Person{firstName:{0}})  RETURN  p")     List<Person>  getPersonWithFirstName  (String  firstName);       @Query(  "MATCH  (p:Person{firstName:{0}})-­‐[:knows]-­‐>friends  "  +    "  RETURN  friends")     Iterable<Person>  findFriendsOfPerson(String  firstName);       }  
  • 76.
    Lessons  Learned   • Be  careful  with  versions  and  upgrading  …   –  Neo  1.9.x  -­‐>  Neo  2.x  =  lots  of  problems…   –  Lots  of  breaking  changes…   –  Spring  Data  Neo4j  !=  Neo4j     •  Nodes  are  “first-­‐class”  ciHzens  in  the  graph   –  Hyperedges  are  not  supported  -­‐>  use  “event  nodes”     •  AggregaHons  are  expensive  –  caching  stats  on  nodes!   •  Unique  and  expressive  relaHonship  types  
  • 77.
    Pi•alls   •  Don’t  use  the  graphid  as  your  ID   •  IniHalize  Set   •  Use  @Fetch  with  care   •  Use  standard  gepers/sepers   •  Be  careful  with  String  escaping  
  • 78.
    InspiraHon   •  Single  Malt  Scotch  Whisky   hpp://gist.neo4j.org/?8139605     •  Chess  Games  and  PosiWons   hpp://gist.neo4j.org/?6506717     •  Movie  RecommendaWons   hpp://gist.neo4j.org/?8173017   •  Food  Recipes  RecommendaWon   hpp://gist.neo4j.org/?8731452