Post on 02-Jul-2015
description
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