$30 off During Our Annual Pro Sale. View Details »

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.

Michelle Sanver

January 14, 2016
Tweet

More Decks by Michelle Sanver

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    This talk is entry-level.

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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?

    View Slide

  24. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Graphs vs. Relational databases
    Relational databases have tables
    Recipes

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  28. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Graphs vs. Relational databases
    Imagine having *actual* relations
    Pasta group Spaghetti Italian group

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  35. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Graphs vs. Relational databases
    Having a flexible schema database costs a lot.

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Graphs and Neo4j
    Labels
    Type:
    Person
    Nick:
    geekie

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Graphs and Neo4j
    You can make art out of your DB.
    (Don’t)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  63. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Neo4j architecture
    Disks
    File System Cache
    Record Files
    Object Cache
    Cypher
    Core API
    Traversal API
    Transaction Management
    Transaction Log

    View Slide

  64. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Hang in there

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    9 bytes

    View Slide

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

    View Slide

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

    View Slide

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

    33 bytes

    View Slide

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

    neostore.propertystore.db.index

    neostore.propertystore.db.strings

    neostore.propertystore.db.arrays

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  91. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Neo4j in PHP
    Neo4jPHP
    PHP Wrapper for the Neo4j graph database REST
    interface
    github.com/jadell/neo4jphp

    View Slide

  92. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Neo4j in PHP
    require('vendor/autoload.php');
    $client =
    new Everyman\Neo4\Client('localhost', 7474);
    print_r($client->getServerInfo());

    View Slide

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

    View Slide

  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();

    View Slide

  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

    View Slide

  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

    View Slide

  97. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    OmNomHub: The Future

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  110. (Michelle)-[:LOVES]->(Neo4j) @michellesanver
    Thank you!

    View Slide

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

    View Slide

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

    View Slide