Top Banner
Leveraging the Power of Graph Databases in PHP Jeremy Kendall Nashville PHP November 2014
97

Leveraging the Power of Graph Databases in PHP

Jul 13, 2015

Download

Technology

Jeremy Kendall
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Leveraging the Power of Graph Databases in PHP

Leveraging the Power of Graph Databases

in PHP

Jeremy Kendall Nashville PHP

November 2014

Page 2: Leveraging the Power of Graph Databases in PHP

Obligatory Intro Slide

Page 3: Leveraging the Power of Graph Databases in PHP

Also - New Father

Page 4: Leveraging the Power of Graph Databases in PHP

What Kind of Database?

Page 5: Leveraging the Power of Graph Databases in PHP

Graphs != Charts

https://www.flickr.com/photos/markgroves/3065192499/

Page 6: Leveraging the Power of Graph Databases in PHP

Graphs != Charts

http://stephenwildish.tumblr.com/post/101408321763/friday-project-witch-moral-compass

Page 7: Leveraging the Power of Graph Databases in PHP

Graph Databases

Page 8: Leveraging the Power of Graph Databases in PHP

Graph Databases• Data Model!

• Nodes with properties

• Typed relationships

Page 9: Leveraging the Power of Graph Databases in PHP

Graph Databases• Data Model!

• Nodes with properties

• Typed relationships

• Strengths!

• Highly connected data

• ACID

Page 10: Leveraging the Power of Graph Databases in PHP

Graph Databases• Data Model!

• Nodes with properties

• Typed relationships

• Strengths!

• Highly connected data

• ACID

• Weaknesses!

• Paradigm shift

Page 11: Leveraging the Power of Graph Databases in PHP

Graph Databases• Data Model!

• Nodes with properties

• Typed relationships

• Strengths!

• Highly connected data

• ACID

• Weaknesses!

• Paradigm shift

• Examples!

• Neo4j, Titan, OrientDB

Page 12: Leveraging the Power of Graph Databases in PHP

Why Care?

Page 13: Leveraging the Power of Graph Databases in PHP

Why Care?• All the NoSQL Joy

• Schema-less

• Semi-structured data

Page 14: Leveraging the Power of Graph Databases in PHP

Why Care?• All the NoSQL Joy

• Schema-less

• Semi-structured data

• Escape from JOIN Hell

Page 15: Leveraging the Power of Graph Databases in PHP

Why Care?• All the NoSQL Joy

• Schema-less

• Semi-structured data

• Escape from JOIN Hell

• Speed

Page 16: Leveraging the Power of Graph Databases in PHP

Why Care?

Page 17: Leveraging the Power of Graph Databases in PHP

Why Care?

• Relationships have 1st class status

Page 18: Leveraging the Power of Graph Databases in PHP

Why Care?

• Relationships have 1st class status

• Just as important as the objects connecting them

Page 19: Leveraging the Power of Graph Databases in PHP

Why Care?

• Relationships have 1st class status

• Just as important as the objects connecting them

• You can have properties & labels

Page 20: Leveraging the Power of Graph Databases in PHP

Why Care?

• Relationships have 1st class status

• Just as important as the objects connecting them

• You can have properties & labels

• Multiple relationships

Page 21: Leveraging the Power of Graph Databases in PHP

Why Care?

Page 22: Leveraging the Power of Graph Databases in PHP

Speed

Depth MySQL Query Time Neo4j Query Time Records Returned

2 0.028 (28 MS) 0.04 ~900

3 0.213 0.06 ~999

4 10.273 0.07 ~999

5 92.613 0.07 ~999

1,000 people with an average 50 friends each

Page 23: Leveraging the Power of Graph Databases in PHP

Crazy SpeedDepth MySQL Query Time Neo4j Query Time Records Returned

2 0.016 (16 MS) 0.01 ~2500

3 30.27 0.168 ~125,000

4 1543.505 1.359 ~600,000

5 Stopped after 1 hour 2.132 ~800,000

1,000,000 people with an average 50 friends each

Page 24: Leveraging the Power of Graph Databases in PHP

Neo4j + Cypher

Page 25: Leveraging the Power of Graph Databases in PHP

Cypher

• Neo4j’s declarative query language

• Easy to pick up

• Some clauses and concepts familiar from SQL

Page 26: Leveraging the Power of Graph Databases in PHP

Simple Example

Page 27: Leveraging the Power of Graph Databases in PHP

Goal

Page 28: Leveraging the Power of Graph Databases in PHP

Create Some NodesCREATE (jk:Person { name: "Jeremy Kendall" })!CREATE (gs:Company { name: "Graph Story" })!!CREATE (tn:State { name: "Tennessee" })!CREATE (memphis:City { name: "Memphis" })!CREATE (nashville:City { name: "Nashville" })!!CREATE (hotchicken:Food { name: "Hot Chicken" })!CREATE (bbq:Food { name: "Barbecue" })!CREATE (photography:Hobby { name: "Photography" })!CREATE (language:Language { name: "PHP" })!!// . . . snip . . .!

Page 29: Leveraging the Power of Graph Databases in PHP

Create Some Relationships

// . . . snip . . .!!CREATE (jk)-[:WORKS_AT { title: {"CTO"}]->(gs),! (jk)-[:LIVES_IN]->(memphis)-[:LIVED_IN]->(nashville),! (hotchicken)-[:ONLY_IN]->(nashville),! (bbq)-[:ONLY_IN]->(memphis),! (jk)-[:LOVES]->(hotchicken),! !// . . . snip . . .!

Page 30: Leveraging the Power of Graph Databases in PHP

Create Some Relationships

// . . . snip . . .!!CREATE (jk)-[:WORKS_AT { title: {"CTO"}]->(gs),! (jk)-[:LIVES_IN]->(memphis)-[:LIVED_IN]->(nashville),! (hotchicken)-[:ONLY_IN]->(nashville),! (bbq)-[:ONLY_IN]->(memphis),! (jk)-[:LOVES]->(hotchicken),! !// . . . snip . . .!

Page 31: Leveraging the Power of Graph Databases in PHP

Create Some Relationships

// . . . snip . . .!!CREATE (jk)-[:WORKS_AT { title: {"CTO"}]->(gs),! (jk)-[:LIVES_IN]->(memphis)-[:LIVED_IN]->(nashville),! (hotchicken)-[:ONLY_IN]->(nashville),! (bbq)-[:ONLY_IN]->(memphis),! (jk)-[:LOVES]->(hotchicken),! !// . . . snip . . .!

Page 32: Leveraging the Power of Graph Databases in PHP

Create Some Relationships

// . . . snip . . .!!CREATE (jk)-[:WORKS_AT { title: {"CTO"}]->(gs),! (jk)-[:LIVES_IN]->(memphis)-[:LIVED_IN]->(nashville),! (hotchicken)-[:ONLY_IN]->(nashville),! (bbq)-[:ONLY_IN]->(memphis),! (jk)-[:LOVES]->(hotchicken),! !// . . . snip . . .!

Page 33: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 34: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 35: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 36: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 37: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 38: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 39: Leveraging the Power of Graph Databases in PHP

Example Cypher Query

MATCH (p:Person { name: "Jeremy Kendall" })-[:LOVES]->(l)!WITH p, l!MATCH (p)-[:WORKS_AT]->(j)!WITH p, l, j!MATCH (p)-[:LIVES_IN]->(c:City)-[:LIVED_IN*0..]->(o:City)!RETURN p, l, j, o

Page 40: Leveraging the Power of Graph Databases in PHP

Query Result

Page 41: Leveraging the Power of Graph Databases in PHP

Neo4j + PHP

Page 42: Leveraging the Power of Graph Databases in PHP

Neo4jPHP• PHP wrapper for the Neo4j REST API

• Installable via Composer

• Used internally at Graph Story

• Used in this presentation

• Well tested

• https://packagist.org/packages/everyman/neo4jphp

Page 43: Leveraging the Power of Graph Databases in PHP

Also see: NeoClient• Written by Neoxygen

• Alternative PHP wrapper for the Neo4j REST API

• Installable via Composer

• Under review for internal use at Graph Story

• Well tested

• https://packagist.org/packages/neoxygen/neoclient

Page 44: Leveraging the Power of Graph Databases in PHP

Connecting$neo4jClient = new \Everyman\Neo4j\Client(! ‘yourgraph.example.com’, ! 7473!);!!$neo4jClient->getTransport()! ->setAuth('username', 'password')! ->getTransport()->useHttps();

Page 45: Leveraging the Power of Graph Databases in PHP

Creating a Node and Label

$node = new Node($neo4jClient);!!$label = $neo4jClient->makeLabel('Person');!!$node->setProperty('name', ‘Jeremy Kendall');!!$node->save()->addLabels(array($label));

Page 46: Leveraging the Power of Graph Databases in PHP

Searching

// Searching for a label by property!$label = $neo4jClient->makeLabel('Person');!$nodes = $label->getNodes('name', $name);

Page 47: Leveraging the Power of Graph Databases in PHP

Querying (Cypher)

$queryString = ! 'MATCH (p:Person { name: { name }}) RETURN p';!!$query = new \Everyman\Neo4j\Cypher\Query(! $neo4jClient,! $queryString,! ['name' => ‘Jeremy Kendall']!);!!$result = $query->getResultSet();

Page 48: Leveraging the Power of Graph Databases in PHP

Named Parameters

Page 49: Leveraging the Power of Graph Databases in PHP

Named Parameters

$queryString = ! 'MATCH (p:Person { name: { name }}) RETURN p';!!$query = new \Everyman\Neo4j\Cypher\Query(! $neo4jClient,! $queryString,! ['name' => ‘Jeremy Kendall']!);!!$result = $query->getResultSet();

Page 50: Leveraging the Power of Graph Databases in PHP

Named Parameters

$queryString = ! 'MATCH (p:Person { name: { name }}) RETURN p';!!$query = new \Everyman\Neo4j\Cypher\Query(! $neo4jClient,! $queryString,! ['name' => ‘Jeremy Kendall']!);!!$result = $query->getResultSet();

Page 51: Leveraging the Power of Graph Databases in PHP

Content Modeling: News Feeds

Page 52: Leveraging the Power of Graph Databases in PHP

News Feed

• Modeled as a list of posts

• Newest post first

• All subsequent posts follow

• Relationships: LASTPOST and NEXTPOST

Page 53: Leveraging the Power of Graph Databases in PHP

LASTPOST

Page 54: Leveraging the Power of Graph Databases in PHP

NEXTPOST

Page 55: Leveraging the Power of Graph Databases in PHP

The Content Modelclass Content!{! public $node;! public $nodeId;! public $contentId;! public $title;! public $url;! public $tagstr;! public $timestamp;! public $userNameForPost;! public $owner = false;!}

Page 56: Leveraging the Power of Graph Databases in PHP

Adding Contentpublic static function add($username, Content $content)!{! $queryString =<<<CYPHER!MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner!CYPHER;!! $query = new Query(! Neo4jClient::client(),! $queryString,! array(! 'u' => $username,! 'title' => $content->title,! 'url' => $content->url,! 'tagstr' => $content->tagstr,! 'timestamp' => time(),! 'contentId' => uniqid()! )! );! $result = $query->getResultSet();!! return self::returnMappedContent($result);!}

Page 57: Leveraging the Power of Graph Databases in PHP

Adding Contentpublic static function add($username, Content $content)!{! $queryString =<<<CYPHER!MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner!CYPHER;!! $query = new Query(! Neo4jClient::client(),! $queryString,! array(! 'u' => $username,! 'title' => $content->title,! 'url' => $content->url,! 'tagstr' => $content->tagstr,! 'timestamp' => time(),! 'contentId' => uniqid()! )! );! $result = $query->getResultSet();!! return self::returnMappedContent($result);!}

Page 58: Leveraging the Power of Graph Databases in PHP

Adding Contentpublic static function add($username, Content $content)!{! $queryString =<<<CYPHER!MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner!CYPHER;!! $query = new Query(! Neo4jClient::client(),! $queryString,! array(! 'u' => $username,! 'title' => $content->title,! 'url' => $content->url,! 'tagstr' => $content->tagstr,! 'timestamp' => time(),! 'contentId' => uniqid()! )! );! $result = $query->getResultSet();!! return self::returnMappedContent($result);!}

Page 59: Leveraging the Power of Graph Databases in PHP

Adding Content

MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner

Page 60: Leveraging the Power of Graph Databases in PHP

Adding Content

MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner

Page 61: Leveraging the Power of Graph Databases in PHP

Adding Content

MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner

Page 62: Leveraging the Power of Graph Databases in PHP

Adding Content

MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner

Page 63: Leveraging the Power of Graph Databases in PHP

Adding Content

MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner

Page 64: Leveraging the Power of Graph Databases in PHP

Adding Content

MATCH (user { username: {u}})!OPTIONAL MATCH (user)-[r:LASTPOST]->(lastpost)!DELETE r!CREATE (user)-[:LASTPOST]->(p:Content { title:{title}, url:{url}, tagstr:{tagstr}, timestamp:{timestamp}, contentId:{contentId} })!WITH p, collect(lastpost) as lastposts!FOREACH (x IN lastposts | CREATE p-[:NEXTPOST]->x)!RETURN p, {u} as username, true as owner

Page 65: Leveraging the Power of Graph Databases in PHP

Adding Content$query = new Query(! $neo4jClient,! $queryString,! array(! 'u' => $username,! 'title' => $content->title,! 'url' => $content->url,! 'tagstr' => $content->tagstr,! 'timestamp' => time(),! 'contentId' => uniqid()! )!);!!$result = $query->getResultSet();

Page 66: Leveraging the Power of Graph Databases in PHP

Retrieving Contentpublic static function getContent($username, $skip)!{! $queryString = <<<CYPHER!MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4!CYPHER;!! $query = new Query(! Neo4jClient::client(),! $queryString,! array(! 'u' => $username,! 'skip' => $skip,! )! );!! $result = $query->getResultSet();!! return self::returnMappedContent($result);!}

Page 67: Leveraging the Power of Graph Databases in PHP

Retrieving Content

MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4

Page 68: Leveraging the Power of Graph Databases in PHP

Retrieving Content

MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4

Page 69: Leveraging the Power of Graph Databases in PHP

Retrieving Content

MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4

Page 70: Leveraging the Power of Graph Databases in PHP

Retrieving Content

MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4

Page 71: Leveraging the Power of Graph Databases in PHP

Retrieving Content

MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4

Page 72: Leveraging the Power of Graph Databases in PHP

Retrieving Content

MATCH (u:User { username: { u }})-[:FOLLOWS*0..1]->f!WITH DISTINCT f, u!MATCH f-[:LASTPOST]-lp-[:NEXTPOST*0..]-p!RETURN p, f.username as username, f = u as owner!ORDER BY p.timestamp desc SKIP { skip } LIMIT 4

Page 73: Leveraging the Power of Graph Databases in PHP

Editing Contentpublic static function edit(Content $content)!{! $updatedAt = time();!! $node = $content->node;! $node->setProperty('title', $content->title);! $node->setProperty('url', $content->url);! $node->setProperty('tagstr', $content->tagstr);! $node->setProperty('updated', $updatedAt);! $node->save();!! $content->updated = $updatedAt;!! return $content;!}

Page 74: Leveraging the Power of Graph Databases in PHP

Editing Contentpublic static function edit(Content $content)!{! $updatedAt = time();!! $node = $content->node;! $node->setProperty('title', $content->title);! $node->setProperty('url', $content->url);! $node->setProperty('tagstr', $content->tagstr);! $node->setProperty('updated', $updatedAt);! $node->save();!! $content->updated = $updatedAt;!! return $content;!}

Page 75: Leveraging the Power of Graph Databases in PHP

Editing Contentpublic static function edit(Content $content)!{! $updatedAt = time();!! $node = $content->node;! $node->setProperty('title', $content->title);! $node->setProperty('url', $content->url);! $node->setProperty('tagstr', $content->tagstr);! $node->setProperty('updated', $updatedAt);! $node->save();!! $content->updated = $updatedAt;!! return $content;!}

Page 76: Leveraging the Power of Graph Databases in PHP

Editing Contentpublic static function edit(Content $content)!{! $updatedAt = time();!! $node = $content->node;! $node->setProperty('title', $content->title);! $node->setProperty('url', $content->url);! $node->setProperty('tagstr', $content->tagstr);! $node->setProperty('updated', $updatedAt);! $node->save();!! $content->updated = $updatedAt;!! return $content;!}

Page 77: Leveraging the Power of Graph Databases in PHP

Editing Contentpublic static function edit(Content $content)!{! $updatedAt = time();!! $node = $content->node;! $node->setProperty('title', $content->title);! $node->setProperty('url', $content->url);! $node->setProperty('tagstr', $content->tagstr);! $node->setProperty('updated', $updatedAt);! $node->save();!! $content->updated = $updatedAt;!! return $content;!}

Page 78: Leveraging the Power of Graph Databases in PHP

Deleting Contentpublic static function delete($username, $contentId)!{! $queryString = self::getDeleteQueryString(! $username, ! $contentId! );!! $params = array(! 'username' => $username,! 'contentId' => $contentId,! );!! $query = new Query(! $neo4jClient,! $queryString, ! $params! );! $query->getResultSet();!}

Page 79: Leveraging the Power of Graph Databases in PHP

Deleting Contentpublic static function delete($username, $contentId)!{! $queryString = self::getDeleteQueryString(! $username, ! $contentId! );!! $params = array(! 'username' => $username,! 'contentId' => $contentId,! );!! $query = new Query(! $neo4jClient,! $queryString, ! $params! );! $query->getResultSet();!}

Page 80: Leveraging the Power of Graph Databases in PHP

Deleting Contentpublic static function delete($username, $contentId)!{! $queryString = self::getDeleteQueryString(! $username, ! $contentId! );!! $params = array(! 'username' => $username,! 'contentId' => $contentId,! );!! $query = new Query(! $neo4jClient,! $queryString, ! $params! );! $query->getResultSet();!}

Page 81: Leveraging the Power of Graph Databases in PHP

Deleting Contentpublic static function delete($username, $contentId)!{! $queryString = self::getDeleteQueryString(! $username, ! $contentId! );!! $params = array(! 'username' => $username,! 'contentId' => $contentId,! );!! $query = new Query(! $neo4jClient,! $queryString, ! $params! );! $query->getResultSet();!}

Page 82: Leveraging the Power of Graph Databases in PHP

Deleting Content: Leaf

// If leaf!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(c:Content { contentId: { contentId }})!WITH c!MATCH (c)-[r]-()!DELETE c, r

Page 83: Leveraging the Power of Graph Databases in PHP

Deleting Content: Leaf

// If leaf!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(c:Content { contentId: { contentId }})!WITH c!MATCH (c)-[r]-()!DELETE c, r

Page 84: Leveraging the Power of Graph Databases in PHP

Deleting Content: Leaf

// If leaf!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(c:Content { contentId: { contentId }})!WITH c!MATCH (c)-[r]-()!DELETE c, r

Page 85: Leveraging the Power of Graph Databases in PHP

Deleting Content: Leaf

// If leaf!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(c:Content { contentId: { contentId }})!WITH c!MATCH (c)-[r]-()!DELETE c, r

Page 86: Leveraging the Power of Graph Databases in PHP

Deleting Content: Leaf

// If leaf!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(c:Content { contentId: { contentId }})!WITH c!MATCH (c)-[r]-()!DELETE c, r

Page 87: Leveraging the Power of Graph Databases in PHP

Deleting Content: LASTPOST

// If last!MATCH (u:User { username: { username }})-[lp:LASTPOST]->(del:Content { contentId: { contentId }})-[np:NEXTPOST]->(nextPost)!CREATE UNIQUE (u)-[:LASTPOST]->(nextPost)!DELETE lp, del, np

Page 88: Leveraging the Power of Graph Databases in PHP

Deleting Content: LASTPOST

// If last!MATCH (u:User { username: { username }})-[lp:LASTPOST]->(del:Content { contentId: { contentId }})-[np:NEXTPOST]->(nextPost)!CREATE UNIQUE (u)-[:LASTPOST]->(nextPost)!DELETE lp, del, np

Page 89: Leveraging the Power of Graph Databases in PHP

Deleting Content: LASTPOST

// If last!MATCH (u:User { username: { username }})-[lp:LASTPOST]->(del:Content { contentId: { contentId }})-[np:NEXTPOST]->(nextPost)!CREATE UNIQUE (u)-[:LASTPOST]->(nextPost)!DELETE lp, del, np

Page 90: Leveraging the Power of Graph Databases in PHP

Deleting Content: LASTPOST

// If last!MATCH (u:User { username: { username }})-[lp:LASTPOST]->(del:Content { contentId: { contentId }})-[np:NEXTPOST]->(nextPost)!CREATE UNIQUE (u)-[:LASTPOST]->(nextPost)!DELETE lp, del, np

Page 91: Leveraging the Power of Graph Databases in PHP

Deleting Content: Other

// All other!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(before),! (before)-[delBefore]->(del:Content { contentId: { contentId }})-[delAfter]->(after)!CREATE UNIQUE (before)-[:NEXTPOST]->(after)!DELETE del, delBefore, delAfter

Page 92: Leveraging the Power of Graph Databases in PHP

Deleting Content: Other

// All other!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(before),! (before)-[delBefore]->(del:Content { contentId: { contentId }})-[delAfter]->(after)!CREATE UNIQUE (before)-[:NEXTPOST]->(after)!DELETE del, delBefore, delAfter

Page 93: Leveraging the Power of Graph Databases in PHP

Deleting Content: Other

// All other!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(before),! (before)-[delBefore]->(del:Content { contentId: { contentId }})-[delAfter]->(after)!CREATE UNIQUE (before)-[:NEXTPOST]->(after)!DELETE del, delBefore, delAfter

Page 94: Leveraging the Power of Graph Databases in PHP

Deleting Content: Other

// All other!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(before),! (before)-[delBefore]->(del:Content { contentId: { contentId }})-[delAfter]->(after)!CREATE UNIQUE (before)-[:NEXTPOST]->(after)!DELETE del, delBefore, delAfter

Page 95: Leveraging the Power of Graph Databases in PHP

Deleting Content: Other

// All other!MATCH (u:User { username: { username }})-[:LASTPOST|NEXTPOST*0..]->(before),! (before)-[delBefore]->(del:Content { contentId: { contentId }})-[delAfter]->(after)!CREATE UNIQUE (before)-[:NEXTPOST]->(after)!DELETE del, delBefore, delAfter

Page 96: Leveraging the Power of Graph Databases in PHP

Questions?

Page 97: Leveraging the Power of Graph Databases in PHP

Thanks! !

[email protected] @JeremyKendall

http://www.graphstory.com