Neo4j is AWESOME!

Neo4j is AWESOME!

Traditional relational databases — ironically — are not that good at the complex relationships some modern applications need.

Multiple joins and complex sub-queries can gradually take a toll on performance.

Graph Databases, on the other hand, are all about relationships. In this talk we will look at using the popular Neo4j graph database with PHP to build efficient relational data for OmNomHub: not your average recipe site.

01da6d807a29ad6d49801c0157518148?s=128

Michelle Sanver

January 14, 2016
Tweet

Transcript

  1. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4J is AWESOME!

  2. (Michelle)-[:LOVES]->(Neo4j) @michellesanver

  3. (Michelle)-[:LOVES]->(Neo4j) @michellesanver WIIIIIIIE \o/ “Learn the most by sharing your

    knowledge with others” - @coderabbi
  4. (Michelle)-[:LOVES]->(Neo4j) @michellesanver This talk is entry-level.

  5. (Michelle)-[:LOVES]->(Neo4j) @michellesanver

  6. (Michelle)-[:LOVES]->(Neo4j) @michellesanver

  7. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Michelle Sanver

  8. @michellesanver (Michelle)-[:LOVES]->(Neo4j) Michelle Sanver Co-President of PHPWomen

  9. @michellesanver (Michelle)-[:LOVES]->(Neo4j) Michelle Sanver Accent(s)!?

  10. @michellesanver (Michelle)-[:LOVES]->(Neo4j) Michelle Sanver

  11. (Michelle)-[:LOVES]->(Neo4j) @michellesanver I’m a backend developer.

  12. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Setting expectations

  13. (Michelle)-[:LOVES]->(Neo4j) @michellesanver How I got into Neo4j

  14. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/

  15. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/ Graph theory has been studied since

    Leonard Euler’s Bridges 1736
  16. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/ Body Text

  17. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/

  18. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/ Graphs are really just connected data…

    They are everywhere
  19. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/

  20. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/ It’s modern.

  21. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/ Facebook open graph

  22. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs \o/ A graph is an easy way

    to visualise connected data. Michelle Graphs likes
  23. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Relational question: Average age

    of everyone in this list? Graph question: Who knows me from third parties?
  24. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Relational databases have tables

    Recipes
  25. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Tables have relationships Recipes

    Groups
  26. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Which causes a join

    table… Recipes Groups RecipeToGroup
  27. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases You query via the

    table Recipes Groups RecipeToGroup
  28. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Imagine having *actual* relations

    Pasta group Spaghetti Italian group
  29. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Recipes Groups RecipeToGroup Pasta

    group Spaghetti Italian group
  30. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Relational databases have a

    structure
  31. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Neo4j has no schema

  32. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases A big query. The

    EAV model.
  33. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases SET @entityid = '3';

    SELECT ea.attribute_id, ea.attribute_code, eav.value AS 'value', 'varchar' AS 'type' FROM catalog_category_entity e JOIN catalog_category_entity_varchar eav ON e.entity_id = eav.entity_id JOIN eav_attribute ea ON eav.attribute_id = ea.attribute_id WHERE e.entity_id = @entityid UNION SELECT ea.attribute_id, ea.attribute_code, eav.value AS 'value', 'int' AS 'type' FROM catalog_category_entity e JOIN catalog_category_entity_int eav ON e.entity_id = eav.entity_id JOIN eav_attribute ea ON eav.attribute_id = ea.attribute_id WHERE e.entity_id = @entityid UNION
  34. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases SELECT ea.attribute_id, ea.attribute_code, eav.value

    AS 'value', 'decimal' AS 'type' FROM catalog_category_entity e JOIN catalog_category_entity_decimal eav ON e.entity_id = eav.entity_id JOIN eav_attribute ea ON eav.attribute_id = ea.attribute_id WHERE e.entity_id = @entityid UNION selecting ea.attribute_id, ea.attribute_code, eav.value AS 'value', 'datetime' AS 'type' FROM catalog_category_entity e JOIN catalog_category_entity_datetime eav ON e.entity_id = eav.entity_id JOIN eav_attribute ea ON eav.attribute_id = ea.attribute_id WHERE e.entity_id = @entityid UNION SELECT ea.attribute_id, ea.attribute_code, eav.value AS 'value', 'text' AS 'type' FROM catalog_category_entity e JOIN catalog_category_entity_text eav ON e.entity_id = eav.entity_id JOIN eav_attribute ea ON eav.attribute_id = ea.attribute_id WHERE e.entity_id = @entityid
  35. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Having a flexible schema

    database costs a lot.
  36. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases For modern complex data…

  37. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs vs. Relational databases Would you still pick

    a relational structure?
  38. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j

  39. (Michelle)-[:LOVES]->(Neo4j) @michellesanver neo4j.org

  40. (Michelle)-[:LOVES]->(Neo4j) @michellesanver neotechnology.com

  41. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Java Based

  42. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Open Source! github.com/neo4j

  43. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Meetups everywhere neo4j.meetup.com

  44. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Graphs have…

  45. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j ( Nodes )

  46. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j (Node) { Properties } As

    many as you want Type: Person Nick: geekie Type: Person Nick: WyriHaximus
  47. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j (Node) [ Relationships ] As

    many as you want Type: Person Nick: geekie Type: Person Nick: WyriHaximus
  48. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Nick: geekie Nick: WyriHaximus knows

    (Node) [ Relationships ] As many as you want
  49. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Labels Type: Person Nick: geekie

  50. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Indexes for easy lookup

  51. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Common named graphs

  52. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Common named graphs Local McLaughlin

    graph
  53. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j Common named graphs Diamond Butterfly

    Bull Franklin Tutte Wagner
  54. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Graphs and Neo4j You can make art out

    of your DB. (Don’t)
  55. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub

  56. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub Like GitHub but for recipes!

  57. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub Fork a recipe

  58. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub See all forks

  59. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub Join groups

  60. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub Search similar recipes

  61. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub Honestly… It’s just a pet project.

  62. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j architecture

  63. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j architecture Disks File System Cache Record Files

    Object Cache Cypher Core API Traversal API Transaction Management Transaction Log
  64. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Hang in there

  65. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j architecture: Traversals

  66. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Traversals Pathexpanders: Define what to traverse

  67. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Traversals Order: Depth-first or breadth-first.

  68. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Traversals Uniqueness : Visit once.

  69. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Traversals Evaluator : Should I stay or should I

    go?
  70. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Traversals Starting nodes: And so it begins.

  71. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j architecture: Cypher and Browser

  72. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Cypher Cypher: SQL for graph databases.

  73. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Cypher ) Parentheses means nodes (Or hugs) (

  74. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Cypher } Curly braces means properties {

  75. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Cypher ] Square brackets means relationships [

  76. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Browser Makes it easy to visualise and query

    the data.
  77. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Browser Let’s learn cypher in the browser!

  78. DEMO: Cypher and Browser (Michelle)-[:LOVES]->(Neo4j) @michellesanver

  79. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j architecture Neostore File Storage

  80. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Several different store files

  81. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Each store has specific data

  82. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Nodes neostore.nodestore.db 9 bytes

  83. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Nodes in-use key: 1 byte

  84. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Fixed size == FAST

  85. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Relationships neostore.relationshipstore.db 33 bytes

  86. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neostore Properties neostore.propertystore.db neostore.propertystore.db.index neostore.propertystore.db.strings neostore.propertystore.db.arrays

  87. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Hardware matters!

  88. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Caching in memory, or filesystem

  89. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP

  90. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP As we saw There’s a

    REST interface!
  91. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP Neo4jPHP PHP Wrapper for the

    Neo4j graph database REST interface github.com/jadell/neo4jphp
  92. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP require('vendor/autoload.php'); $client = new Everyman\Neo4\Client('localhost',

    7474); print_r($client->getServerInfo());
  93. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP Use $client to do anything!

  94. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP Creating a node with the

    client $recipe = $client->makeNode(); $recipe->setProperty('title', ‘Spaghetti Bolognese') ->setProperty('Description', ‘Italian words') ->setProperty('Ingredients', ‘A lot') ->save(); $recipe->getId();
  95. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP You get the idea, it’s

    well documented! Use $client to do anything, even Cypher queries. https://github.com/jadell/neo4jphp/wiki
  96. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Neo4j in PHP In OmNomHub we’re using Symfony2

    There’s a bundle for that. https://github.com/klaussilveira/neo4j-client-bundle
  97. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub: The Future

  98. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub: The Future Connecting users “You both like”

  99. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub: The Future Connecting recipes “These have similar

    ingredients and user base”
  100. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub: The Future Being smart “You might like”

  101. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub: The Future Being smart Smart recipe collections!

  102. (Michelle)-[:LOVES]->(Neo4j) @michellesanver OmNomHub: The Future Being creepy “Don’t like meat

    huh?”
  103. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Wrapup

  104. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Wrapup Graphs are everywhere

  105. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Wrapup They make it easy to connect data

  106. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Wrapup Easier to be creepy <3

  107. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Wrapup OmNomHub will be EPIC :D

  108. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Wrapup Open Source! https://github.com/Omnomhub

  109. Resources (Michelle)-[:LOVES]->(Neo4j) @michellesanver docs.neo4j.org Graph Databases - Ian Robinson, 


    neo technology gives you the e-book version for free. neo4j.org/learn
  110. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Thank you!

  111. (Michelle)-[:LOVES]->(Neo4j) @michellesanver Questions?

  112. (Michelle)-[:LOVES]->(Neo4j) @michellesanver How would you use it?