Ph pn rio 2012 - conheça seu primeiro banco de dados orientado a grafos

Preview:

DESCRIPTION

Palestra apresentada no PHPnRIo 2013. Pequena introdução sobre NoSQL e o modelo de grafos. Explicação de como o Neo4J funciona e exemplificação utilizando códigos. Finalizando com um pequeno exemplo de rede social com Neo4J e PHP.

Citation preview

Conheça seu primeiro banco de dados orientado

a GRAFOSJean Carlo Nascimento aka Suissa

GRAFOWTF?

parent_id é um grafo

Quem inventou isso?

Euler foi um dos mais prolíficos matemáticos,

calcula-se que toda a sua obra reunida teria entre

60 e 80 volumes.Fonte: Wikipedia, mas eu boto fé!

● Número de Euler● Fórmula de Euler● Constante de Euler-Mascheroni● Conjectura de Euler● Igualdade de Euler● Teorema de Euler● Teoria dos grafos

Leonhard Euler

Paguei pau.

De onde surgiu esse manolo?

Por que ele fez isso?

Por quê?!Ah é nessa época não tinha internet.

Sete pontes de Königsberg

● Transações ACID● 32 bilhões de nós● 32 bilhões de relacionamentos● 64 bilhoões de propriedades● REST API ou JVM Embedded

Neo4J

Mas isso não é muito novo?

Modelo Relacional

1970

Grafos

1736

Tudo muito bonito mas qual a diferença?

O custo da busca local de um grafo continua o

mesmo independente do seu tamanho.

Cypher

REST APIAMEN!

Criar um novo nó vazio

POST http://localhost:7474/db/data/node201 Created

POST http://localhost:7474/db/data/node {"nome":"Suissa"}201 Created

Ler um nó

GET http://localhost:7474/db/data/node/27200 Ok

GET http://localhost:7474/db/data/node/666404 Not Found

Deleta um nó

DELETE http://localhost:7474/db/data/node/26204 No Content*Um nó com relacionamento não pode ser deletado

POST http://localhost:7474/db/data/node {"name":"NoSQL"}POST http://localhost:7474/db/data/node/27/relationships {"to" : "http://localhost:7474/db/data/node/28", "type" : "Evangeliza"}DELETE http://localhost:7474/db/data/node/27409 Conflict

Primeiro o relacionamentoDELETE http://localhost:7474/db/data/relationship/1204 No Content

DELETE http://localhost:7474/db/data/node/27204 No Content

E para deletar todos os nós?

Adicionando propriedadesPOST http://localhost:7474/db/data/node201 Created

PUT http://localhost:7474/db/data/node/29/properties/idade 28204 No Content

PUT http://localhost:7474/db/data/node/29/properties {"nome":"Suissa", "idade":28, "cursos":["neo4j", "mongodb"]}

*Um valor de propriedade não pode ser nulo ou um objeto JSON.

Adicionando propriedades

Estes dois comandos irão falhar:PUT http://localhost:7474/db/data/node/29/properties {"nome":"Suissa", "idade":28, "cursos":null}PUT http://localhost:7474/db/data/node/29/properties {"nome":"Suissa", "idade":28, "cursos":{"nosql":"mongodb", "nosql":"neo4j"}}

Mas estes irão funcionarPUT http://localhost:7474/db/data/node/29/properties {"nome":"Suissa", "idade":28, "cursos":""}PUT http://localhost:7474/db/data/node/29/properties {"nome":"Suissa", "idade":28, "cursos": "{\"nosql\":\"mongodb\", \"nosql\":\"neo4j\"}" }

Modificando uma propriedadePUT http://localhost:7474/db/data/node/29/properties/nome "Cumpadi Uóxinton"204 No Content

PUT http://localhost:7474/db/data/node/29/properties {"nome": "Cumpadi Uóxinton"}204 No Content

Deletando uma propriedadeDELETE http://localhost:7474/db/data/node/29/properties/cursos

Deletando todas as propriedadesDELETE http://localhost:7474/db/data/node/29/properties

Atravessando nósPOST http://localhost:7474/db/data/node/13/traverse/nodeAccept: application/jsonContent-Type: application/json{ "order": "breadth_first", "return_filter": { "body": "position.endNode().getProperty('name').toLowerCase().contains('t')", "language": "javascript" }, "prune_evaluator": { "body": "position.length() > 10", "language": "javascript" }, "uniqueness": "node_global", "relationships": [{ "direction": "all", "type": "knows" }, { "direction": "all", "type": "loves" }], "max_depth": 3}

Atravessando relacionamentosPOST http://localhost:7474/db/data/node/6/traverse/relationshipAccept: application/jsonContent-Type: application/json{ "order" : "breadth_first", "uniqueness" : "none", "return_filter" : { "language" : "builtin", "name" : "all" }}

Atravessando relacionamentos[ { "start" : "http://localhost:7474/db/data/node/6", "data" : { }, "self" : "http://localhost:7474/db/data/relationship/1", "property" : "http://localhost:7474/db/data/relationship/1/properties/{key}", "properties" : "http://localhost:7474/db/data/relationship/1/properties", "type" : "know", "extensions" : { }, "end" : "http://localhost:7474/db/data/node/5"}, { "start" : "http://localhost:7474/db/data/node/6", "data" : { }, "self" : "http://localhost:7474/db/data/relationship/2", "property" : "http://localhost:7474/db/data/relationship/2/properties/{key}", "properties" : "http://localhost:7474/db/data/relationship/2/properties", "type" : "own", "extensions" : { }, "end" : "http://localhost:7474/db/data/node/4"} ]

Atravessando caminhosPOST http://localhost:7474/db/data/node/9/traverse/pathAccept: application/jsonContent-Type: application/json{ "order" : "breadth_first", "uniqueness" : "none", "return_filter" : { "language" : "builtin", "name" : "all" }}

Atravessando caminhos[ { "start" : "http://localhost:7474/db/data/node/9", "nodes" : [ "http://localhost:7474/db/data/node/9" ], "length" : 0, "relationships" : [ ], "end" : "http://localhost:7474/db/data/node/9"}, { "start" : "http://localhost:7474/db/data/node/9", "nodes" : [ "http://localhost:7474/db/data/node/9", "http://localhost:7474/db/data/node/8" ], "length" : 1, "relationships" : [ "http://localhost:7474/db/data/relationship/3" ], "end" : "http://localhost:7474/db/data/node/8"}, { "start" : "http://localhost:7474/db/data/node/9", "nodes" : [ "http://localhost:7474/db/data/node/9", "http://localhost:7474/db/data/node/7" ], "length" : 1, "relationships" : [ "http://localhost:7474/db/data/relationship/4" ], "end" : "http://localhost:7474/db/data/node/7"} ]

Todos os comandos também funcionam para

as relaçõesSó trocar node por relationship

Todos os tipos de relacionamentosGET http://localhost:7474/db/data/relationship/types200 OK["Evangeliza","CONHECE","Ama"]

*Uma vez criado um relacionamento ele não pode mais ser deletado

E o PHP mano?

cURL

Alternativas● https://github.com/onewheelgood/Neo4J-REST-PHP-

API-client● https://github.com/lphuberdeau/Neo4j-PHP-OGM● https://github.com/jadell/neo4jphp

Neo4J.phpuse Everyman\Neo4j\Client,

Everyman\Neo4j\Transport,Everyman\Neo4j\Node,Everyman\Neo4j\Relationship;

$client = new Client(new Transport('localhost', 7474));

Neo4J.php$keanu = new Node($client);$keanu->setProperty('name', 'Keanu Reeves')->save();

$laurence = new Node($client);$laurence->setProperty('name', 'Laurence Fishburne')->save();

$matrix = new Node($client);$matrix->setProperty('title', 'The Matrix')->save();

$constantine = new Node($client);$constantine>setProperty('title', 'Constantine')->save();

Neo4J.php$keanu->relateTo($matrix, 'IN')->save();$keanu->relateTo($constantine, 'IN')->save();$laurence->relateTo($matrix, 'IN')->save();

echo $keanu->getProperty('name') . " filmou:\n";$relationships = $laurence->getRelationships('IN');foreach ($relationships as $relationship) { $movie = $relationship->getEndNode(); echo "\t" . $movie->getProperty('title') . "\n";}

Object Graph Modelfunction findRecommendations(User $user){

return $em->createCypherQuery()->startWithNode('user', $user)->match('user -[:follow]-> followedBy <-[:follow]- similarInterest')->match('similarInterest -[:follow]-> potentialMatch')->end('potentialMatch', 'count(*)')->order('count(*) DESC')->limit(10)->getList();

}

Perguntas?

Recommended