• Save
Neo4what?
Upcoming SlideShare
Loading in...5
×
 

Neo4what?

on

  • 762 views

Talk presented @JustJava 2013

Talk presented @JustJava 2013
Sources @ https://github.com/tiagobento/neo4j
Eder Ignatowicz and Tiago Bento Fernandes
Neo4j Java Gremlim Cypher REST Graph

Statistics

Views

Total Views
762
Views on SlideShare
751
Embed Views
11

Actions

Likes
0
Downloads
0
Comments
0

1 Embed 11

https://twitter.com 11

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Neo4what? Neo4what? Presentation Transcript

    • Neo4 what?A practical guide to Graph DatabasesFriday, June 7, 13
    • @ederign /tiagobentoFriday, June 7, 13
    • DextraGalera ponta firme que manda bemAmbiente de melhoria contínuaProjetos desafiadoresQualidade de vidaFriday, June 7, 13
    • DATABIGFriday, June 7, 13
    • Every 2 days we create asmuch information as wedid up to 2003”Eric Schmidt, Google“Friday, June 7, 13
    • Our data is moreconnectedText (content)HyperText (addedpointers)RSS (joined thosepointers)Blogs (addedpingbacks)Friday, June 7, 13
    • Data is more complexand semi-structuredFriday, June 7, 13
    • If you tried to collect allthe data of every musicalbum ever made, howwould you model it?Friday, June 7, 13
    • ReleaseDateComposerTrackArtistAlbumhasplayed on hascomposed byparticipated onhasFriday, June 7, 13
    • ComposerAlbumparticipated onhasidNamerelease_dateartAlbum!idnamebirthComposer!album_idComposer_idAlbumComposer!Friday, June 7, 13
    • You have to stretch your data(and your domain model)to fit in relational databasesLose semantics Accidental complexityObject-relational impedance mismatchTearsFriday, June 7, 13
    • There is no“one size fits all”approachFriday, June 7, 13
    • Key-ValueColumn FamilyDocumentGraphNot Only SQLFriday, June 7, 13
    • The right toolfor the right jobFriday, June 7, 13
    • Dont be a hipsterRDBMS&ComplexityBigTableClonesSizeKey-ValueStoreDocumentDatabasesGraphDatabases90% ofUse CasesRelationalDatabasesFriday, June 7, 13
    • Why should I usea graph database?Friday, June 7, 13
    • Graphs areeverywhereFriday, June 7, 13
    • Highly connected data (social networks)Recommendations (e-commerce)Path Finding (how do i know you)A* (Least Cost path)Data First Schema (bottom-up)Schema EvolutionBest fits forFriday, June 7, 13
    • The world is connectedFriday, June 7, 13
    • Property graphFriday, June 7, 13
    • What is a graph database?A database with an explicit graph structureEach node knows its adjacent nodesAs the number of the nodes increases,the cost of a local step (or hop) remains thesamePlus a index for lookupsFriday, June 7, 13
    • Neo4jTHE graph databaseFriday, June 7, 13
    • Graph Database + Lucene IndexProperty GraphEmbeddable and serverREST interfaceStableFriday, June 7, 13
    • Full ACID (atomicity, consistency, isolation, durability)High Availability (with Enterprise Edition)32 Billion Nodes32 Billion Relationships64 Billion PropertiesSchema freeFriday, June 7, 13
    • # persons query timeRelationaldatabase1000 2000msNeo4j 1000 2msNeo4j 1000000 2msSocial network“path exists”~1k persons~ 50 friends/personspathExists(a,b)depth 4Friday, June 7, 13
    • If you’ve everJoined more than 7 tables togetherModeled a graph in a tableFells icky when need to “adapt” yourER model to fit on a DBTried to write some crazy view/storedprocedure with multiple recursive self an innerjoinsFriday, June 7, 13
    • You should useFriday, June 7, 13
    • Neo4jFriday, June 7, 13
    • Neo4jStarting the serverFriday, June 7, 13
    • EmbeddedGraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH); <dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j</artifactId> <version>1.9</version> </dependency>Friday, June 7, 13
    • Standaloneneo4j-community-1.9 tiagobento$ bin/neo4j startStarting Neo4j Server...WARNING: not changing userprocess [80169]... waiting for server to be ready..... OK.Go to http://localhost:7474/webadmin/for administration interface.Friday, June 7, 13
    • Friday, June 7, 13
    • Friday, June 7, 13
    • Manipulating dataFriday, June 7, 13
    • CypherNeo4j’s Query LanguageFriday, June 7, 13
    • CREATE( _1 { name: "Radiohead" }),( _2 { name: "The Black Keys" }),( _3 { name: "Joy Division" }),( _4 { name: "Los hermanos" }),( _5 { name: "Oasis" }),( _6 { name: "Daft Punk" }),( _7 { name: "Felguk" }),( _8 { name: "Deadmau5" }),( eder { name: "Eder Ignatowicz", age: 22 }),( tiago { name: "Tiago Bento", age: 19 }),Friday, June 7, 13
    • Tiago BentoEder IgnatowiczOasisLos hermanosJoy DivisionThe Black KeysRadioheadDaft PunkDeadmau5FelgukFriday, June 7, 13
    • eder-[:LIKES]->_8,eder-[:LIKES]->_7,eder-[:LIKES]->_6,eder-[:LIKES]->_5,eder-[:LIKES]->_4,tiago-[:LIKES]->_6,tiago-[:LIKES]->_5,tiago-[:LIKES]->_4,tiago-[:LIKES]->_3,tiago-[:LIKES]->_2,tiago-[:LIKES]->_1RETURN *Friday, June 7, 13
    • Tiago BentoEder IgnatowiczOasisLos hermanosJoy DivisionThe Black KeysRadioheadDaft PunkDeadmau5FelgukFriday, June 7, 13
    • Tiago BentoEder IgnatowiczOasisLos hermanosJoy DivisionThe Black KeysRadioheadDaft PunkDeadmau5FelgukLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESFriday, June 7, 13
    • Tiago BentoEder IgnatowiczOasisLos hermanosJoy DivisionThe Black KeysRadioheadDaft PunkDeadmau5FelgukLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESFriday, June 7, 13
    • Eder LIKES?Friday, June 7, 13
    • [ "Deadmau5", "Felguk", "Daft Punk", "Oasis", "Los hermanos" ]START ed=node(9)MATCH (ed)-[:LIKES]->(a)RETURN collect(a.name);Friday, June 7, 13
    • Tiago BentoEder IgnatowiczOasisLos hermanosJoy DivisionThe Black KeysRadioheadDaft PunkDeadmau5FelgukLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESLIKESFriday, June 7, 13
    • Eder TiagoLIKES LIKES?Friday, June 7, 13
    • [ "Daft Punk", "Oasis", "Los hermanos" ]START ti=node(10), ed=node(9)MATCH (ed)-[:LIKES]->(a)<-[:LIKES]-(ti)RETURN collect(a.name);Musical compatibilityFriday, June 7, 13
    • [ "Daft Punk" ]START ti=node(10), ed=node(9)MATCH (ed)-[:LIKES]->(a)<-[:LIKES]-(ti)WHERE a.name =~ "(?i)D.*"RETURN collect(a.name);Musical compatibilityFriday, June 7, 13
    • GremlinChaining navigationFriday, June 7, 13
    • Friday, June 7, 13
    • GremlinFriday, June 7, 13
    • ==> ==>          ,,,/==>          (o o)==> -----oOOo-(_)-oOOo-----==> ==> Available variables:==>   g = (neo4jgraph[EmbeddedGraphDatabase [data/graph.db]]==> , null)  out = (java.io.PrintStream@14c55ea==> , null)gremlin>Friday, June 7, 13
    • g.addVertex(1, [name: "Lion", size: "Big" ]);g.addVertex(2, [name: "Aligator", size: "Big" ]);g.addVertex(3, [name: "Zebra", size: "Big" ]);g.addVertex(4, [name: "Deer", size: "Big" ]);g.addVertex(5, [name: "Giraf", size: "Huge" ]);...Friday, June 7, 13
    • g.addEdge(g.v(1), g.v(3), EATS);g.addEdge(g.v(1), g.v(4), EATS);g.addEdge(g.v(1), g.v(5), EATS);g.addEdge(g.v(1), g.v(7), EATS);g.addEdge(g.v(1), g.v(6), EATS);...Friday, June 7, 13
    • Aligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • Lion EATS EATS?Not relevantFriday, June 7, 13
    • Start pointAligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • Aligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • Aligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • g.v(1).out(EATS).out(EATS).name.unique().sort()Lion’s IDBeeFishGrassHoneyShrimpFriday, June 7, 13
    • g.v(1).out(EATS).loop(1){it.loops == 2}.name.unique().sort()BeeFishGrassHoneyShrimpLion’s IDFriday, June 7, 13
    • Java APICypher Queries ExecutionTraversal FrameworkFriday, June 7, 13
    • ExecutionEngine ee = new ExecutionEngine(graphDb);ExecutionResult result = ee.execute("START n=node(1) RETURN n;");Iterator<Node> columns = result.columnAs("n");for (Node node : IteratorUtil.asIterable(columns)) {System.out.println(node.getProperty("name"));}First nodeCypherFriday, June 7, 13
    • Traversal FrameworkTraverse through your dataFriday, June 7, 13
    • Lion EATS EATS?Not relevantFriday, June 7, 13
    • Start pointAligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • Aligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • Aligator ZebraHumanBearFishLionGirafShrimpDeerBeeGrassPlanctonHoneyEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSEATSFriday, June 7, 13
    • Node lion = graphDb.getNodeById(LION_ID); TraversalDescription td = Traversal.description() .depthFirst() .relationships(RelationshipTypes.EATS, Direction.OUTGOING) .evaluator(Evaluators.atDepth(2)).uniqueness(Uniqueness.NODE_LEVEL); for (Node node : td.traverse(lion).nodes()) { System.out.println(node.getProperty("name")); }BeeHoneyFishShrimpGrassFood chainFriday, June 7, 13
    • Node lion = graphDb.getNodeById(LION_ID);TraversalDescription td = Traversal.description() .depthFirst() .relationships(RelationshipTypes.EATS, Direction.OUTGOING) .evaluator(Evaluators.atDepth(2)).uniqueness(Uniqueness.NODE_LEVEL); for (Path path : td.traverse(lion)) { System.out.println(path); }Food chain(1)--[EATS,4]-->(6)--[EATS,22]-->(9)(1)--[EATS,4]-->(6)--[EATS,11]-->(13)(1)--[EATS,4]-->(6)--[EATS,10]-->(7)(1)--[EATS,3]-->(7)--[EATS,12]-->(8)(1)--[EATS,2]-->(5)--[EATS,9]-->(11)Friday, June 7, 13
    • REST APIFull power through HTTP RequestsFriday, June 7, 13
    • DELETE PUTGETPOSTNodesRelationshipsNode LabelsIndexesTransactionsFriday, June 7, 13
    • DELETE PUTGETPOSTNodesRelationshipsNode LabelsIndexesTransactionsFriday, June 7, 13
    • POST http://localhost:7474/db/data/transactionTRANSACTIONPOST http://localhost:7474/db/data/transaction/7{  "statements" : [ {    "statement" : "CREATE n RETURN n"  } ]}POST http://localhost:7474/db/data/transaction/7/commitPOST http://localhost:7474/db/data/transaction/7{  "statements" : [ {    "statement" : "START n=node(1) DELETE n"  } ]}Friday, June 7, 13
    • DELETE PUTGETPOSTNodesRelationshipsNode LabelsIndexesTransactionsFriday, June 7, 13
    • {  "extensions" : {  },  "paged_traverse" : "http://localhost:7474/db/data/node/5/paged/traverse/{returnType}{?pageSize,leaseTime}",  "labels" : "http://localhost:7474/db/data/node/5/labels",  "outgoing_relationships" : "http://localhost:7474/db/data/node/5/relationships/out",  "traverse" : "http://localhost:7474/db/data/node/5/traverse/{returnType}",  "all_typed_relationships" : "http://localhost:7474/db/data/node/5/relationships/all/{-list|&|types}",  "property" : "http://localhost:7474/db/data/node/5/properties/{key}",  "all_relationships" : "http://localhost:7474/db/data/node/5/relationships/all",  "self" : "http://localhost:7474/db/data/node/5",  "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/5/relationships/out/{-list|&|types}",  "properties" : "http://localhost:7474/db/data/node/5/properties",  "incoming_relationships" : "http://localhost:7474/db/data/node/5/relationships/in",  "incoming_typed_relationships" : "http://localhost:7474/db/data/node/5/relationships/in/{-list|&|types}",  "create_relationship" : "http://localhost:7474/db/data/node/5/relationships", "data" : {    "foo" : "bar"  }}• POST http://localhost:7474/db/data/node• Accept: application/json• Content-Type: application/json{  "foo" : "bar"}• 201: Created• Content-Length: 1156• Content-Type: application/json• Location: http://localhost:7474/db/data/node/5Friday, June 7, 13
    • • POST http://localhost:7474/db/data/cypher• Accept: application/json• Content-Type: application/json{  "columns" : [ "TYPE(r)" ],  "data" : [ [ "know" ] ]}{  "query" :"START x  = node:node_auto_index(name={startName})MATCH path = (x-[r]-friend)WHERE friend.name = {name}RETURN TYPE(r)",  "params" : {    "startName" : "Tiago Bento",    "name" : "Eder Ignatowicz"  }}• 200: OK• Content-Type: application/jsonFriday, June 7, 13
    • Friday, June 7, 13
    • @ederign /tiagobentoFriday, June 7, 13