Introduรงรฃo ร  linguagem de consulta Cypher

A linguagem de consulta Cypher foi originalmente desenvolvida especificamente para o DBMS grรกfico Neo4j . O objetivo do Cypher รฉ fornecer uma linguagem de consulta de banco de dados SQL legรญvel por humanos para bancos de dados de grรกficos. Hoje, o Cypher รฉ suportado por vรกrios DBMSs de grรกficos. O OpenCypher foi criado para padronizar o Cypher.


As noรงรตes bรกsicas de trabalho com o DBMS do Neo4j sรฃo descritas no artigo Noรงรตes bรกsicas de trabalho com o Neo4j em um navegador .


Para se familiarizar com Cypher, considere um exemplo de uma รกrvore genealรณgica emprestada do clรกssico livro de Prolog de I. Bratko. Este exemplo mostra como adicionar nรณs e links a um grรกfico, como atribuir rรณtulos e atributos a eles e como fazer perguntas.


รrvore genealรณgica no Neo4j, vista editada


Entรฃo, vamos ter uma รกrvore genealรณgica mostrada na figura abaixo.


รrvore genealรณgica


Vamos ver como formar o grรกfico correspondente no Cypher:


CREATE (pam:Person {name: "Pam"}), (tom:Person {name: "Tom"}), (kate:Person {name: "Kate"}), (mary:Person {name: "Mary"}), (bob:Person {name: "Bob"}), (liz:Person {name: "Liz"}), (dick:Person {name: "Dick"}), (ann:Person {name: "Ann"}), (pat:Person {name: "Pat"}), (jack:Person {name: "Jack"}), (jim:Person {name: "Jim"}), (joli:Person {name: "Joli"}), (pam)-[:PARENT]->(bob), (tom)-[:PARENT]->(bob), (tom)-[:PARENT]->(liz), (kate)-[:PARENT]->(liz), (mary)-[:PARENT]->(ann), (bob)-[:PARENT]->(ann), (bob)-[:PARENT]->(pat), (dick)-[:PARENT]->(jim), (ann)-[:PARENT]->(jim), (pat)-[:PARENT]->(joli), (jack)-[:PARENT]->(joli) 

Uma solicitaรงรฃo CREATE para adicionar dados a um DBMS grรกfico consiste em duas partes: adicionando nรณs e adicionando links entre eles. Cada nรณ a ser adicionado recebe um nome na estrutura desta solicitaรงรฃo, que รฉ usada para criar links. Nรณs e comunicaรงรตes podem armazenar documentos. No nosso caso, os nรณs contรชm documentos com os campos de nome e os links do documento nรฃo. Tambรฉm nรณs e links podem ser rotulados. No nosso caso, os nรณs recebem o rรณtulo Pessoa e os links sรฃo PAI. O rรณtulo nas solicitaรงรตes รฉ destacado por dois pontos antes do nome.


Portanto, o Neo4j nos disse que: Added 12 labels, created 12 nodes, set 12 properties, created 11 relationships, completed after 9 ms.


Vamos ver o que temos:


 MATCH (p:Person) RETURN p 

รrvore genealรณgica em Neo4j


Ninguรฉm nos proรญbe de editar a aparรชncia do grรกfico resultante:


รrvore genealรณgica no Neo4j, vista editada


O que pode ser feito com isso? Vocรช pode verificar se, por exemplo, Pam รฉ
Pai de Bob:


 MATCH ans = (:Person {name: "Pam"})-[:PARENT]->(:Person {name: "Bob"}) RETURN ans 

Obtemos o subgrรกfico correspondente:


Pam รฉ mรฃe de Bob


No entanto, isso nรฃo รฉ exatamente o que precisamos. Altere a solicitaรงรฃo:


 MATCH ans = (:Person {name: "Pam"})-[:PARENT]->(:Person {name: "Bob"}) RETURN ans IS NOT NULL 

Agora, em resposta, nos tornamos true . E se perguntarmos:


 MATCH ans = (:Person {name: "Pam"})-[:PARENT]->(:Person {name: "Liz"}) RETURN ans IS NOT NULL 

Nรฃo receberemos nada ... Aqui vocรช precisa adicionar a palavra OPTIONAL , se
o resultado estarรก vazio e false serรก retornado:


 OPTIONAL MATCH ans = (:Person {name: "Pam"})-[:PARENT]->(:Person {name: "Liz"}) RETURN ans IS NOT NULL 

Agora temos a resposta esperada false .


Em seguida, vocรช pode ver quem รฉ o pai de quem:


 MATCH (p1:Person)-[:PARENT]->(p2:Person) RETURN p1, p2 

Abra a guia de resultados com Text e veja uma tabela com duas colunas:


 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"p1" โ”‚"p2" โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚{"name":"Pam"} โ”‚{"name":"Bob"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Tom"} โ”‚{"name":"Bob"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Tom"} โ”‚{"name":"Liz"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Kate"}โ”‚{"name":"Liz"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Mary"}โ”‚{"name":"Ann"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Bob"} โ”‚{"name":"Ann"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Bob"} โ”‚{"name":"Pat"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Dick"}โ”‚{"name":"Jim"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Ann"} โ”‚{"name":"Jim"} โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Pat"} โ”‚{"name":"Joli"}โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚{"name":"Jack"}โ”‚{"name":"Joli"}โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

O que mais podemos aprender? Por exemplo, quem รฉ o pai de um membro especรญfico do gรชnero, por exemplo, para Bob:


 MATCH (parent:Person)-[:PARENT]->(:Person {name: "Bob"}) RETURN parent.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"parent.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pam" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Aqui, como resposta, nรฃo solicitamos o nรณ inteiro, mas apenas seu atributo especรญfico.


Tambรฉm podemos descobrir quem sรฃo os filhos de Bob:


 MATCH (:Person {name: "Bob"})-[:PARENT]->(child:Person) RETURN child.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"child.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Ann" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Tambรฉm podemos perguntar quem tem filhos:


 MATCH (parent:Person)-[:PARENT]->(:Person) RETURN parent.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"parent.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Pam" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Kate" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Mary" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Dick" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Ann" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Jack" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Hmm, Tom e Bob se conheceram duas vezes, conserte:


 MATCH (parent:Person)-[:PARENT]->(:Person) RETURN DISTINCT parent.name 

Adicionamos a palavra DISTINCT ao resultado de retorno da consulta, o que significa
semelhante ao do SQL.


 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"parent.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Pam" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Kate" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Mary" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Dick" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Ann" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Jack" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Vocรช tambรฉm pode perceber que o Neo4j nos devolve os pais na ordem em que foram inseridos na solicitaรงรฃo CREATE .


Vamos agora perguntar quem รฉ avรด ou avรณ:


 MATCH (grandparent:Person)-[:PARENT]->()-[:PARENT]->(:Person) RETURN DISTINCT grandparent.name 

ร“timo, รฉ isso:


 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"grandparent.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pam" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Mary" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

No modelo de consulta, usamos um nรณ sem nome intermediรกrio () e duas relaรงรตes do tipo PARENT .


Agora descobrimos quem รฉ o pai. O pai รฉ um homem que tem um filho. Assim, nos faltam dados sobre quem รฉ o homem. Assim, para determinar quem รฉ mรฃe, vocรช precisa saber quem รฉ mulher. Adicione as informaรงรตes relevantes ao nosso banco de dados. Para isso, atribuiremos os rรณtulos Male e Female aos nรณs existentes.


 MATCH (p:Person) WHERE p.name IN ["Tom", "Dick", "Bob", "Jim", "Jack"] SET p:Male 

 MATCH (p:Person) WHERE p.name IN ["Pam", "Kate", "Mary", "Liz", "Ann", "Pat", "Joli"] SET p:Female 

Vamos explicar o que fizemos aqui: selecionamos todos os nรณs rotulados como Person , verificamos eles
a propriedade name acordo com a lista especificada entre colchetes e atribuiu aos nรณs correspondentes o rรณtulo Male ou Female respectivamente.


Verifique:


 MATCH (p:Person) WHERE p:Male RETURN p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Dick" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Jack" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Jim" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

 MATCH (p:Person) WHERE p:Female RETURN p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Pam" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Kate" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Mary" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Liz" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Ann" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Joli" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Solicitamos todos os nรณs rotulados Person , que tambรฉm possuem um rรณtulo Male ou Female , respectivamente. Mas poderรญamos tornar nossos pedidos um pouco diferentes:


 MATCH (p:Person:Male) RETURN p.name MATCH (p:Person:Female) RETURN p.name 

Vamos dar uma olhada no nosso grรกfico novamente:


รrvore genealรณgica com tags Masculino e Feminino


O Neo4j Browser pintou os nรณs em duas cores diferentes, de acordo com as marcas Masculino e
Feminino


Ok, agora podemos consultar todos os pais do banco de dados:


 MATCH (p:Person:Male)-[:PARENT]->(:Person) RETURN DISTINCT p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Tom" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Dick" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Jack" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

E mรฃes:


 MATCH (p:Person:Female)-[:PARENT]->(:Person) RETURN DISTINCT p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Pam" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Kate" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Mary" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Ann" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Vamos agora formular um relacionamento de irmรฃo e irmรฃ. X รฉ irmรฃo de Y,
se ele รฉ homem, e para X e Y hรก pelo menos um pai em comum. Da mesma forma para
irmรฃ de relacionamento.


Atitude do irmรฃo em Cypher:


 MATCH (brother:Person:Male)<-[:PARENT]-()-[:PARENT]->(p:Person) RETURN brother.name, p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"brother.name"โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Bob" โ”‚"Liz" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Atitude de irmรฃ em Cypher:


 MATCH (sister:Person:Female)<-[:PARENT]-()-[:PARENT]->(p:Person) RETURN sister.name, p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"sister.name"โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Liz" โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Ann" โ”‚"Pat" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚"Ann" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Assim, podemos descobrir quem รฉ o pai e quem รฉ o avรด ou a avรณ. Mas e os ancestrais mais distantes? Com os bisavรดs, os bisavรณs ou assim por diante? Nรฃo escreveremos uma regra correspondente para cada um desses casos, e serรก sempre mais problemรกtica. De fato, tudo รฉ simples: X รฉ um ancestral para Y se for um ancestral para um pai Y. Cypher fornece um padrรฃo * que permite exigir uma sequรชncia de relaรงรตes de qualquer tamanho:


 MATCH (p:Person)-[*]->(s:Person) RETURN DISTINCT p.name, s.name 

Existe realmente um problema nisso: serรฃo quaisquer conexรตes. Adicione uma referรชncia ao link PARENT :


 MATCH (p:Person)-[:PARENT*]->(s:Person) RETURN DISTINCT p.name, s.name 

Para nรฃo aumentar o comprimento do artigo, encontramos todos os ancestrais de Joli :


 MATCH (p:Person)-[:PARENT*]->(:Person {name: "Joli"}) RETURN DISTINCT p.name 

 โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•• โ”‚"p.name"โ”‚ โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ก โ”‚"Jack" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pat" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Bob" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Pam" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚"Tom" โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

Considere uma regra mais complexa para descobrir quem estรก relacionado a quem.
Primeiro, parentes sรฃo ancestrais e descendentes, por exemplo, filho e mรฃe, avรณ e neto. Em segundo lugar, parentes sรฃo irmรฃos e irmรฃs, incluindo primos, primos em segundo grau e assim por diante, o que em termos de antepassados โ€‹โ€‹significa que eles tรชm um ancestral em comum. E em terceiro lugar, parentes que tรชm descendentes em comum, por exemplo, marido e mulher, sรฃo considerados parentes.


No Cypher, vocรช precisa usar o UNION para muitos padrรตes:


 MATCH (r1:Person)-[:PARENT*]-(r2:Person) RETURN DISTINCT r1.name, r2.name UNION MATCH (r1:Person)<-[:PARENT*]-(:Person)-[:PARENT*]->(r2:Person) RETURN DISTINCT r1.name, r2.name UNION MATCH (r1:Person)-[:PARENT*]->(:Person)<-[:PARENT*]-(r2:Person) RETURN DISTINCT r1.name, r2.name 

Aqui, na primeira regra, as conexรตes sรฃo usadas, cuja direรงรฃo nรฃo importa para nรณs. Essa conexรฃo รฉ indicada sem uma seta, apenas um traรงo - . A segunda e terceira regra sรฃo escritas de uma maneira รณbvia e familiar.


Nรฃo apresentaremos o resultado da consulta total aqui, apenas dizeremos que os pares de parentes encontrados sรฃo 132, o que รฉ consistente com o valor calculado como o nรบmero de pares ordenados de 12. Tambรฉm podemos especificar essa consulta substituindo a ocorrรชncia da variรกvel r1 ou r2 por (:Person {name: "Liz"}) por exemplo, no entanto, no nosso caso, isso nรฃo faz muito sentido, pois todas as pessoas em nosso banco de dados sรฃo obviamente parentes.


Isso conclui nossa discussรฃo sobre a identificaรงรฃo de relacionamentos entre pessoas em nosso banco de dados.


Por fim, considere como remover nรณs e links.


Para excluir todas as nossas pessoas, vocรช pode executar a solicitaรงรฃo:


 MATCH (p:Person) DELETE p 

No entanto, o Neo4j nos dirรก que vocรช nรฃo pode excluir nรณs que possuem links.
Portanto, primeiro excluรญmos os links e depois repetimos a remoรงรฃo dos nรณs:


 MATCH (p1:Person)-[r]->(p2:Person) DELETE r 

O que fizemos agora: comparou duas pessoas entre as quais hรก uma conexรฃo, nomeou essa conexรฃo como r depois a excluiu.


Conclusรฃo


O artigo mostra como usar os recursos da linguagem de consulta Cypher usando um exemplo simples de um grรกfico social. Em particular, examinamos como adicionar nรณs e links com uma consulta, como procurar dados relacionados, inclusive com links indiretos, e como atribuir rรณtulos aos nรณs. Mais informaรงรตes sobre o Cypher podem ser encontradas nos links abaixo. Um bom ponto de partida รฉ o "Neo4j Cypher Refcard".


O Neo4j estรก longe de ser o รบnico grรกfico DBMS. Entre os outros mais populares estรฃo Cayley , Dgraph com linguagem de consulta GraphQL, multi-modelo ArangoDB e OrientDB . De particular interesse pode ser o Blazegraph, com suporte para RDF e SPARQL.


Referรชncias



Bibliografia


  • Robinson Jan, Weber Jim, Eifrem Emil. Bases de dados de grรกficos. Novos recursos
    por trabalhar com dados relacionados / Por. do inglรชs - 2ยช ed. - M.: DMK-Press,
    2016 - 256 s.
  • Bratko I. Programaรงรฃo em linguagem Prolog para inteligรชncia artificial:
    trans. do inglรชs - M .: Mir, 1990 - 560 p .: doente.

Posfรกcio


O autor do artigo conhece apenas duas empresas (ambas de Sรฃo Petersburgo) que usam DBMSs grรกficos para seus produtos. Mas eu gostaria de saber quantas empresas de leitores deste artigo as utilizam em seu desenvolvimento. Portanto, proponho participar da pesquisa. Escreva tambรฉm sobre sua experiรชncia nos comentรกrios, serรก muito interessante saber.

Source: https://habr.com/ru/post/pt482418/


All Articles