Neo4j Daten natürlich modellieren und verarbeiten mit Neo4j (graphs)-[:are]->(everywhere) Patrick Baumgartner @patbaumgartner JavaLand.eu Phantasialand 26. März 2014
Speaker Profil Patrick Baumgartner Graph & Code Talent @ 42talents Spring Framework, OSGi, Neo4j Spring Trainer Co-Autor von "OSGi für Praktiker" Agile Projektmethoden & Praktiken Scrum.org Trainer - PSD Java @patbaumgartner 2
42talents Qualifiziert in den Bereichen Spring Framework Java EE OSGi Agile Projektmethoden Standort Zürich, Schweiz @42talents http://www.42talents.com 3
Agenda Einführung Usecases Neo4j Querying Import / Export Tools und APIs Polyglot Persistence Highlights & Challenges beim Einsatz Q & A 4
New Types of Data Stores 5
NoSQL Data Size Key-Value Stores Column Family Document Databases Graph Databases 90% aller Usecases Relational Datatabases Data Complexity 6
Labeled Property Graph Modell Graphen bestehen aus Knoten / Nodes Beziehungen / Relations Eigenschaften / Properties Labels Bob Person name:bob age:63 sex:male name:alice age:21 sex:female Person Alice type:drives type:owns S Car Model: S vendor:tesla 7
Usecases Wo finde ich meinen Graphen? 8
Social Data Alice KNOWS Carol KNOWS Luke Bob KNOWS Pete KNOWS Sam 9
Social Graph Ein einmaliger Anwendungsfall? 10
Spatial Data 1 type:road length:3km ROAD 2 5 type:hotel name:radisson Blu lat:47.452549 long:8.564615 type:hotel name:widder lat:47.373517 long:8.539252 3 8 ROAD ROAD 13 11
Schienennetz in Deutschland 12
Social & Spatial Data Alice KNOWS LIKES Mat 5 type:hotel name:radisson Blu lat:47.452549 long:8.564615 Bob ROAD 8 ROAD 13 13
Financial Data Alice OWNS Hotel TRANSFER Luke Bank Pete WITHDRAW ATM 14
Eine beliebige Business Domäne Process Device KPI Activity DEPENDS_ON Service DEPENDS_ON Function 15
Single Malt Scotch Whisky GraphGist http://gist.neo4j.org/?8139605 16
Single Malt Scotch Whisky GraphGist http://gist.neo4j.org/?8139605 17
Neo4j The Big Picture 18
Neo4j Big Picture Die verbreitetste Graphendatenbank der Welt Robust: In Betrieb 24/7 seit 2003 Reifegrad: Vielfach in Produktion ausgerollt Community: Ecosystem mit Tools, Bindings, Frameworks Lizenzen AGPLv3 Community Edition OpenSource Advanced/Enterprise für kommerzielle Anwendungen Neo Technology Entwicklung & Support ~ 60 Personen / 6 Länder / 3 Kontinente Total 24 Mio $ VC Finanzierung 19
Data Browser 20
Eigenschaften Objektorientiert, flexible Netzwerkstruktur Support für ACID Transaktionen Vertikal skalierbar Java API Anbindung mittels Java, Groovy, Scala, JRuby Runtime Standalone Server Embedded Database Diskbasierter Storage Manager Support für Erweiterungen und Testing 21
Querying Wie finde ich meine Daten? 22
Graph Querying Wie erhalte ich die richtigen Nodes aus dem Graphen? Nenne mir alle Freunde und Freunde von Freunden, welche den Film XY mit mehr als 3 Sternen bewertet haben.... Queryingmethoden Traversing mit Neo4j API Traversal Descriptions Graphalgorithmen Index Queries Cypher Queries 23
Neo4j API Node bob =...; for ((Relationship rel: bob.getrelationships(reltypes.knows)) { Node friend = rel.getendnode(); System.out.println(friend.getProperty("name")); } Einfache, aber sehr "low level" API Zu "verbose" für komplexe Traversals 24
Traversal API Beschreibt Bewegungen durch den Graphen Callback basiert Abfrage API für Graphen Fluent API Konstrukte Neo4j implementiert folgende Algorithmen: A* Dijkstra pathswithlength shortestpath allsimplepaths allpaths 25
Traversal API Konstrukte 26
Beispiel: Traversal API TraversalDescription directfriends = Traversal.description().breadthFirst().relationships(RelTypes.KNOWS).evaluator(Evaluators.toDepth(1)).evaluator(Evaluators.excludeStartPosition()); for(path p : directfriends.traverse(bob)) { } System.out.println(p.endNode().getProperty("firstname")); 27
Index Queries Unterstützung von Node und Relationship Indices Lucene als Standard-implementierung node id property value 15 name Alice 15 yearofbirth 1972 16 name Bob 46 name Carol 46 yearofbirth 1983 28
Cypher Query Language Graph Query Language ähnlich SQL Deklarative Sprache Definiert das "Was" nicht das "Wie" Nutzt Pattern Matching Support für Filterung Paginierung Update-Funktionalität 29
Cypher Query Language Elemente Element START MATCH WHERE SKIP LIMIT RETURN ORDER BY PARAMETERS CREATE Bedeutung Startelement(e) (Angabe von Index- o. Id-Lookup) Pattern für zu findende Knoten, beschrieben durch Pfade auf Identifiern (a) [knows]-> (b) Resultatsfilterung (boolean-ausdruck) Paginierung Definiert Rückgabe-Elemente Sortierung nach Properties Parameter-Map, die im Cypher mittels Key oder Position verwendet werden kann Erzeugt einen Knoten 30
Beispiel: Cypher Query & Java String query = "MATCH (person)-[:knows]-(friend) " + "RETURN friend"; KNOWS person friend ExecutionEngine engine = new ExecutionEngine(graphDb); ExecutionResult result = engine.execute(query); Iterator<Object> column = result.columnas("friend"); while(column.hasnext()) { Node friendnode = (Node)column.next(); } System.out.println(friendNode.getProperty(PROP_FIRSTN AME)); 31
Example: Cypher Create Query CREATE (carol {name:"carol"}) return carol; +----------------------------+ carol +----------------------------+ Node[1]{name:"carol"} +----------------------------+ Carol CREATE (bob {name:"bob"}), (carol)-[:knows]->(bob) return bob; KNOWS Carol Bob CREATE (apple {name:"apple",type:"fruit"}), (carol)-[:owns {number: 5}]->(apple); Carol OWNS number: 5 Apple type: Fruit 32
Import / Export Wie lese und schreibe ich Daten? 33
Erzeugung von Nodes mit Java org.neo4j.graphdb.graphdatabaseservice graphdb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH); Transaction tx = graphdb.begintx(); try { Node peter = createnode(graphdb, "Peter"); Node carol = createnode(graphdb, "Carol"); peter.createrelationshipto(carol, RelTypes.KNOWS);.. tx.success(); } finally {tx.finish();} public Node createnode(graphdatabaseservice graphdb, String firstname) { Node person = graphdb.createnode(); person.setproperty("firstname", firstname); return person; } 34
Erzeugung von Nodes mit Cypher MERGE (carol:person{name:'carol'}); MERGE (bob:person{name:'bob'}); MERGE (trudy:person{name:'trudy'}); MERGE (apple:fruit{name:'apple'}); MERGE (bob)-[:knows]->(carol); MERGE (bob)-[:knows]->(trudy); MERGE (trudy)-[:knows]->(carol); MERGE (carol)-[:owns{number: 5}]->(apple); 35
NeoClipse 36
Thinkerpop Blueprint Thinkerpop Blueprint Extensions GraphML Reader/Writer Library GraphSon Reader/Writer Library GML Reader/Writer Library Java Universal Network/ Graph Framework 37
GraphML GraphML (http://graphml.graphdrawing.org/ ) Standardisierte Beschreibungssprache für Graphen Modellierungswerkzeuge XML <graph id="g" edgedefault="directed"> <node id="n0"/> <node id="n1"/> <edge source="n0" target="n1"/> </graph> 38
Tools & APIs Nützliche Helfer bei der täglichen Arbeit 39
Neo4j Bordmittel Admin Console Daten Visualisierung Cypher Neo4j Shell Cypher REST Interface Cypher Neo4j Plugin Eigenentwicklung CSV BatchInserter ParallelBatchInserter 40
Tools & APIs Third Party Libraries Thinkerpop Spring Data Neo4j (SDN)... 41
Spring Data Verwendet die selben Prinzipien wie das Spring Framework Produktivitätssteigerung Konsistentes Programmiermodell Portabilität Überprojekt für diverse Mapperimplementationen Mappingunterstützung für Java Domainobjekte http://www.springsource.org/spring-data http://github.com/springsource/spring-data-xxx 42
Spring Data Neo4j (SDN) POJOs auf Nodes & Relationships typensicher gemappt Arbeitet direkt mit der Datenbank, normalerweise im Embedded-Mode Alles passiert innerhalb einer @Transaction Braucht AspectJ um die POJOs mit Magie zu erweitern 43
Spring Data Neo4j NodeEntity @NodeEntity public class Person { private String name; } private int age; // getters/setters Alice Person alice = new Person(); alice.setname("alice"); alice.setage(42); alice.persist(); 44
Spring Data Neo4j Relationship @RelationshipEntity public class Knows { private int sinceyear; public Knows since(int year) { this.sinceyear = year; return this; } } @NodeEntity public class Person { public Known knows(person p) { return this.relateto(p, Knows.class, "KNOWS"); } } Person alice =...; Person bob...; KNOWS alice.knows(bob).since(2012); Alice Bob since: 2012 45
Spring Data Neo4j NodeEntity @NodeEntity public class Person { private String name; private int yearofbirth; @RelatedTo(type = "KNOWS", direction = Direction.OUTGOING) private Set<Person> knownpersons; public void knows(person p) { knownpersons.add(p); } public Set<Person> getfriends() { return knownpersons; } } Person alice =...; alice.knows(bob); alice.knows(carol); Alice KNOWS KNOWS Carol Bob 46
Spring Data Neo4j Repository public interface PersonRepository extends GraphRepository<Person> { } @Query("start person = {0} match... return...") Iterable<Product> getownedservices(person person); Iterable<Person> findbyname(string name); Iterable<Person> findbynamelike(string name); @Autowired PersonRepository personrepository; Person alice = personrepository.findbyname("alice"); 47
Polyglot Persistence Gibt es nur EINEN zentralen Datentopf? 48
Polyglot Persistence Applikation User Sessions Shopping Card Recommendations Redis Riak Neo4j Product Catalog Analytics Financial Data MongoDB Casandra MySQL 49
Challenges and Highlights 50
Challenges Developer Onboarding "Schemaänderungen" -> Migrationen Extrem viele Daten Oft neue Neo4j Releases Bugs keine Showstopper Übersicht im Modell nicht verlieren / Dokumentation pflegen 51
Highlights Community mit gutem Support Sourcen auf Github Gute Performance Whiteboard friendliness Spring Programmier-Modell mit Spring Data Neo4j 52
Q&A 53
Herzlichen Dank! (graphs)-[:are]->(everywhere) Patrick Baumgartner, @patbaumgartner patrick.baumgartner [at] 42talents [dot] com http://www.42talents.com @42talents 54