Introduction to Neo4j and Spring Data

Post on 02-Jul-2015

137 views 5 download

description

Slides from my talk on Neo4j and Spring Data, given at JavaBin Sørlandet and JavaBin Vestfold. The slides are in Norwegian - I will upload an English version soon.

Transcript of Introduction to Neo4j and Spring Data

Introduksjon  ,l  grafdatabaser,  Neo4j  og  Spring  Data  

 Aleksander  M.  Stensby  

Monokkel  A/S  

•  Daglig  leder  i  Monokkel  AS  

•  Tidligere  COO  i  Integrasco  AS  

•  Persistering,  Prosessering  og  Presentasjon  av  data  

Persistering  –  Prosessering  –  Presentasjon  

•  Aleksander  M.  Stensby  

•  Daglig  leder  i  Monokkel  AS  

•  Tidligere  COO  i  Integrasco  AS  

www.monokkel.io  

Agenda  

•  Intro  @l  grafdatabaser  og  modellering    

•  Neo4j  og  Cypher    

•  SpringData  Neo4j  

Relasjondatabaser...  

...på  relasjoner  

Relasjondatabaser  er  fantas@sk  på  aggregering  av  data,  mapping  av  

skjemaer  og  tabell  data!  

MEN  

vi  har  en  tendens  @l  å  tvinge    _alle_    

problems@llinger  inn  i  relasjondatabasene  våre!  

Join-­‐hell..  Rekursjon...  

Null-­‐sjekking...  

Polyglot  persistering  

NoSQL  

Not  only  SQL  

NoSQL  

•  Key-­‐value  stores  – Amazon  Dynamo  – Eks:  Voldemort,...  

•  BigTable  kloner  – Google’s  BigTable  – Eks:  Hbase,  ...  

•  Dokumentdatbaser  – Lotus  Notes  – Eks:  MongoDB,  CouchDB  

NoSQL  

•  Grafdatabaser  – Euler  og  graXeori  – Eks:  Neo4j,  VertexDB,  AllegroGraph,  Giraphe,  OrientDB,  etc...  

NoSQL  Størrelse  

Kompleksitet  

Grafer  

Dokument  

BigTable  

KV  

NoSQL  Størrelse  

Kompleksitet  

Grafer  

Dokument  

BigTable  

KV  

90%  Milliarder  av  noder  og  relasjoner  

dagens  dose  buzzwords  

Venner  av  venner...  

Person  ID  Navn  

Venner  PersonID  VennID  

Person  ID  Navn  

Venner  PersonID  VennID  

«Aleks»  sine  venner  

SELECT  p1.Person  FROM  Person  p1  JOIN  Venner  

 ON  Venner.VennID  =  p1.ID  JOIN  Person  p2  

 ON  Venner.PersonID  =  p2.ID  WHERE  p2.Navn  =  'Aleks'  

Person  ID  Navn  

Venner  PersonID  VennID  

Venner  med  «Aleks»  

SELECT  p1.Person  FROM  Person  p1  JOIN  Venner  

 ON  Venner.PersonID  =  p1.ID  JOIN  Person  p2  

 ON  Venner.VennID  =  p2.ID  WHERE  p2.Navn  =  'Aleks'  

Person  ID  Navn  

Venner  PersonID  VennID  

«Aleks»  sine  venners  venner?  

SELECT  p1.Person  AS  PERSON,  p2.Person  AS  VENN_AV_VENN  FROM  Venner  v1  JOIN  Person  p1  

 ON  v1.PersonID  =  p1.ID  JOIN  Venner  v2  

 ON  v2.VennID  =  v1.VennID  JOIN  Person  p2  

 ON  v2.VennID  =  p2.  ID  WHERE  p1.Navn  =  'Aleks‘  AND  v2.VennID  <>  p1.ID  

Kilde:  Neo4j  in  Ac@on  

1,000,000  personer  

Dybde   RDBMS   Neo4j   Antall  rader  

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  

En  grafdatabase...  

•  benyper  grafstrukturer  med  – Noder  – Relasjoner    – Apribuper    

•  @l  å  lagre  informasjon!  

•  Ypperlig  @l  relasjoner  –  men  ikke  best  på  aggregering  av  data  

Grafdatabaser  og  neo4j  

•  Visuelt  –  Skjemaløst!    

•  Dobbelt-­‐lenkede-­‐lister    – hver  node  har  en  liste  med  innkommende  og  utgående  relasjoner  

•  Direkte  lookup  =  O(1)  

En  graf  lagrer  data  i  noder  

ALEKS   TARJEI  

Relasjoner  knyper  noder  sammen  

FRIENDS_WITH  

ALEKS   TARJEI  

Noder  har  a\ribu\er  

ALEKS   TARJEI  

Age:  29  First  Name:  Aleksander  Last  Name:  Stensby    

Age:  30  First  Name:  Tarjei  Last  Name:  Romtveit    

FRIENDS_WITH  

Relasjoner  kan  også  ha  a\ribu\er  

ALEKS   TARJEI  

Age:  29  First  Name:  Aleksander  Last  Name:  Stensby    

Age:  30  First  Name:  Tarjei  Last  Name:  Romtveit    

FRIENDS_WITH  Since:  01.01.2004  

Relasjoner  kan  gå  flere  veier  

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  

forskjellige  typer  av  noder  

Person   Person  

Sport  

Programmeringspråk  

Drikke  

Person  

Noen  bruksområder  

•  Sosiale  Medier  •  Recommenda@ons  •  Geo  rou@ng  og  logis@kk  •  Brukerkontroll  /  @lgangshåndtering  •  Network  management  •  Finans  /  Svindel  

Neo4j  –  [ER_EN]  -­‐>  Property  Graph  

(node)  –  [relasjon]  -­‐>  (node)  

(Aleks)  –  [FRIENDS_WITH]  -­‐>  (Tarjei)  

Cypher  

"Make  the  simple  things  simple,  and  the  complex  things  possible"  

Intro  @l  Cypher  

•  START  •  MATCH  •  WHERE  •  RETURN  •  CREATE  •  DELETE  •  SET  •  FOREACH  •  WITH  

MATCH  <papern>    WHERE  RETURN    

Beskriv  hva  du  ønsker  å  hente  ut  med  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.@tle  =  ‘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  

Venners  venner...  

MATCH  (aleks)-­‐[:KNOWS*2..2]-­‐>(friend_of_friend)  WHERE  aleks.firstName=  'Aleks'  RETURN  friend_of_friend.firstName  

Venners  venner...  

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.5/  

         

på  1-­‐2-­‐3    DEMO  

 

Og  mye  mye  mer...  •  Traversals  navigerer  grafen  •  Traversals  iden@fiserer  paths  •  Paths  ordner  noder  •  Cypher  parametere  •  Indexes  •  Neo4j  embedded,  Neo4j  REST  •  Neo4j  2.x  –  Labels  og  automaaske  indekser  •  Gremlin  (procedural)  –  Cypher  (declara@ve)  •  Enterprise  (mul@-­‐instance  cluster,  online  backup)  •  Neo4j  Spaaal  

Språkdrivere  

Contrib  

Intro  @l  SpringData  Neo4j  

•  SpringData  •  Repositories  •  Kjapt  eksempel  på  oppsep  

<dependencies>          <dependency>                  <groupId>org.springframework.data</groupId>                  <ar@factId>spring-­‐data-­‐neo4j</ar@factId>                  <version>3.2.0.RELEASE</version>          </dependency>  </dependencies>  

neo4j      2.1.4  spring-­‐data-­‐neo4j    3.2.0  spring      4.1.0  

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  -­‐  Domene  

@NodeEntity  public  class  Person  {  @GraphId  public  Long  nodeId;    @Indexed(unique  =  true)  public  int  id;    public  String  firstName;  public  String  lastName;  }  

1-­‐1  relasjoner  

@NodeEntity  public  class  Address  {    private  Country  country;    ...  }  

1-­‐1  relasjoner  

@NodeEntity  public  class  Address  {    @Fetch  private  Country  country;    ...  }  

1-­‐m  relasjoner  -­‐  @RelatedTo  

@RelatedTo(type  =  "ADDRESS")  private  Set<Address>  addresses  =  new  HashSet<Address>();  

@RelatedTo  private  Set<Person>  venner  =  new  HashSet<Person>  ();  

m-­‐m  relasjoner  -­‐  @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  

public  interface  PersonRepository  extends  GraphRepository<Person>{}  

@Autowired  PersonRepository  repository;  

SpringData  Neo4j  -­‐  Repositories  

public  interface  PersonRepository  extends  GraphRepository<Person>{      findByFirstName(String  firstName);    }  

SpringData  Neo4j  -­‐  Repositories  

public  interface  PersonRepository  extends  GraphRepository<Person>{      Person  findByFirstName(String  firstName);    @Query("MATCH  (p:Person{firstName:{0}})  RETURN  p")    Person  getPersonWithFirstName  (String  firstName);    }  

SpringData  Neo4j  -­‐  Repositories  

public  interface  PersonRepository  extends  GraphRepository<Person>{      Person  findByFirstName(String  firstName);    @Query("MATCH  (p:Person{firstName:{0}})  RETURN  p")    Person  getPersonWithFirstName  (String  firstName);      @Query(  "MATCH  (p:Person{firstName:{0}})-­‐[:knows]-­‐>friends  "  +  

 "  RETURN  friends")    Iterable<Person>  findFriendsOfPerson(String  firstName);      }  

Lessons  Learned  •  Vær  forsik@g  med  versjoner  og  oppgraderinger…  – Neo  1.9.x  -­‐>  Neo  2.x  kan  by  på  mange  problemer  – Mange  breaking  changes  underveis…  –  Spring  Data  Neo4j  !=  Neo4j    

•  Noder  er  “first-­‐class”  ci@zens  I  grafen  – Hyperedges  støpes  ikke  -­‐>  kan  bruke  “event  nodes”    

•  Dyrt  å  aggregere  -­‐  caching  av  stats  på  noder!  

•  Unike  og  ekspressive  relasjonstyper  

Pi�alls  •  Ikke  bruk  graphid  som  ID  

•  Ini@aliser  alle  Set  

•  Bruk  @Fetch,  men  vær  forsik@g  

•  Bruk  standard  gepers/sepers  

•  Vær  varsom  med  String  escaping  

Inspirasjon  •  Single  Malt  Scotch  Whisky  

hpp://gist.neo4j.org/?8139605    

•  Chess  Games  and  Posiaons  hpp://gist.neo4j.org/?6506717    

•  Movie  Recommendaaons  hpp://gist.neo4j.org/?8173017  

•  Food  Recipes  Recommendaaon  hpp://gist.neo4j.org/?8731452