🔵 Primeiros passos com Neo4j e Cypher
Tags: neo4j, nosql, database, braziliandevs
Published: 2022-05-29 22:49:57

Neste post vamos aprender a dar os primeiros passos com o banco de dados orientado à grafos Neo4j e sobre sua linguagem de conculta Cypher.

* [O que são grafos?](#grafos)
 - [Relacionamentos (Arestas)](#relacionamentos)
* [Base de exemplo Movie Graph](#exemplo) 
* [Propriedades de um nó e de um relacionamento](#propriedades)
* [Linguagem de Consulta Cypher](#cypher)
 - [Principais palavras](#principais)
 - [Guardando comandos (favoritando)](#favoritando)
* [Criando nós (nodes)](#criando-nos)
 - [Criando um nó apenas com id](#criando-no-id)
 - [Criando um nó com label](#criando-no-label)
 - [Criando um nó com propriedades](#criando-no-propriedades)
 - [Escolhendo como o nó deve aparecer](#como-aparecer)
 - [Usando o comando WHERE](#comando-where)
 - [Criando nós estruturados](#criando-nos-estruturados)
 - [Usando o comando CONTAINS](#comando-contains)
* [Criando relacionamentos (arestas)](#criando-relacionamentos)
 - [Relacionamento bidirecional](#bidirecional)
 - [Pesquisando relacionamentos](#pesquisando-relacionamentos)
 - [Apagando relacionamentos](#apagando-relacionamentos)
 - [Usando o comando MERGE](#comando-merge)
 - [Tarefa](#tarefa)

[![A Jornada do Autodidata em Inglês](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkoqkmh9hic17tnddjf6.png)](https://go.hotmart.com/R93865620U)

# O que são grafos? <a name="grafos">

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3pv7aioohtpp4vjtpwam.png)

Conforme a [Wikipédia](https://pt.wikipedia.org/wiki/Teoria_dos_grafos), a teoria dos grafos ou de grafos é um ramo da matemática que estuda as relações entre os objetos de um determinado conjunto. Para tal são utilizadas estruturas chamadas grafos, `G(V,E)`, onde `V` é um __conjunto não vazio de objetos__ denominados vértices (ou nós) e `E` (do inglês edges - arestas) é um __subconjunto de pares não ordenados__ de V.



# Relacionamentos (Arestas) <a name="relacionamentos">

__Neo4j__ é usado muito em rede de buscas e recomendações. Por exemplo, você busca um filme na Netflix e, de acordo com esse filme, você obtêm recomendações.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hy2kvncxl4fxgjghrf3.png) 
 
 
 

# Base de exemplo Movie Graph <a name="exemplo">

Para as próximas etapas você precisa ter o [Neo4j Desktop](https://neo4j.com/download/) instalado.

Clique em start:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avhxodmxvj9pm0w8729l.png) 

Clique em open:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pm4vlkvh7o25lkpebh99.png)

Clique em cada passo:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzyeog2x7j4y8rhipien.png)
  
O comando `:play movie-graph` foi programado para mostrar a tela abaixo:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsu6fjiysemtnxramy90.png)

Após clicar na seta ao lado, é mostrado o comando para criar toda a base de dados. Você pode rodar o comando de duas maneiras:

1. Você pode clicar direto no play:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bbgpz5jeei730kvvmmq.png) 

2. Ou você pode clicar no comando e depois no play:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qspdg0e0jif31zw4x4s2.png)
  
Após teremos os seguintes dados:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cpw2elqns9z5q80l676k.png)
 

[![Formação TS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isxopdurvofcx18iptvb.png)](https://go.hotmart.com/H93763859E)


# Propriedades de um nó e de um relacionamento <a name="propriedades"> 

Label e propriedades de um nó:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d91ky8g695al6wnpbkha.png)

Comparando com um banco de dados relacional, a `Label` é como se fosse o nome de uma tabela e, as `propriedades`, como se fossem as colunas de uma tabela. As `propriedades` podem diferir em cada nó, pois o __Neo4j__ não é um banco de dados estruturado e, sim, um banco de dados __nosql__.

Tipos de relacionamento e suas propriedades:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33fbafsz3lkx49u7ga7f.png)
 
Após uma consulta, o resultado abaixo apresenta dois `Node Labels` e dois `Relationship Types`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o58uxc9uov3gzvaksgsq.png)
 
  
 
# Linguagem de Consulta Cypher <a name="cypher">

[Cypher](https://neo4j.com/developer/cypher/) é a linguagem de consulta de gráficos do Neo4j que permite recuperar dados do gráfico. Inspirado pelo SQL, permite que você se concentre em quais dados você deseja do gráfico (não em como obtê-los). É a linguagem gráfica mais fácil de aprender devido a sua semelhança com outras linguagens e intuitividade.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zybvet8f56bugxvl7or9.png)
 

# Principais palavras da linguagem Cypher <a name="principais">

Você pode executar o comando `Neo4j$ :help cypher`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tc0sbbxzog81tjc5od6.png)

* `CREATE` - Cria nodes e relacionamentos;
* `MATCH` - Parecido com o comando `select` do banco de dados relacional;
* `RETURN` - Mostra (retorna) o valor criado;
* `WHERE` - Seleciona dados através de uma determinada condição;
* `SET` - Atualização;
* `REMOVE` - Deleção;
* `MERGE` - Cria um objeto derivado de algum node.



# Guardando comandos (favoritando) <a name="favoritando">


Você pode guardar comandos que mais utiliza:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5z4ovm1hn74v9e617zs.png)

Para salvar um comando é só clicar no play para executar ele e depois clicar na estrela:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70tz5g9mn8ckvyge8lar.png)

Salve o comando de __buscar todos os dados__:

```cypher
MATCH (n) DETACH DELETE n
``` 

E salve o comando de __deletar todos os dados__:

```cypher
MATCH (n) RETURN n
``` 

 
[![Formação TS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72gnny6fjwnmku1x3rr4.png)](https://go.hotmart.com/H93763859E)


# Criando nós (nodes) <a name="criando-nos">

Primeiro vamos deletar todos os dados do exemplo Movie Graph com o comando:

```cypher
MATCH (n) DETACH DELETE n
```

Não podemos ter relacionamentos se não tivermos nós. Então, vamos criar por primeiro os nós.


# Criando um nó apenas com id <a name="criando-no-id">

Os parenteses `()` representam um nó.

Execute o comando `CREATE ()` para criar um nó:
```cypher
CREATE ()
```

Já temos um nó criado, mas sem label e apenas com a propriedade id. Para buscar todas as informações utilize o comando:

```cypher
MATCH (n) RETURN n
```

Observamos que o nosso nó só tem id:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4do6szqcaxq3t1ega3y.png)
 
Podemos já criar o node e retorná-lo com o comando:

```cypher
CREATE (n) RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtsp38gbfdthhx699dkz.png)
 

Agora temos um nó com o id 1. O `n` é uma variável (representando um nó) criada em tempo de execução e não será guardada em memória para ser utilizada depois; você pode colocar qualquer nome no lugar de `n`.

Se selecionarmos todos os dados teremos dois nós, um com `id 0` e outro com `id 1`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1shnmznvqe0g40byth4.png)
 

# Criando um nó com label <a name="criando-no-label">

1. Tudo que for criado para o nó será colocado dentro de `()`. 
2. Dentro de `()`, a variável vem sempre primeiro.
3. __Case sensitive:__ a label `Time` diferirá da label `time`.

```cypher
CREATE (n :Time) RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7g87mqixgtnsog03h8kf.png)

Se você rodar esse comando mais duas vezes teremos três times:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xgtt6bkstbp6p3q7c0gz.png)
 
Criando um nó com duas labels:

```cypher
CREATE (n :Time :Basquete) RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4senb4pb6slh5gitubt.png)
 
Agora temos quatro times e um deles é de basquete:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spa2koxp6gbasxmdi4i5.png)
 

# Criando um nó com propriedades <a name="criando-no-propriedades">

As propriedades são criadas dentro de `{}`. 

Criando e retornando com a variável `n`:
```cypher
CREATE (n :Time :Futebol {nome: 'Internacional', cor: 'Vermelho e Branco'}) RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/broy42zjncbebx2eejqx.png)

Criando, mas sem retornar:

```cypher
CREATE (:Time :Futebol {nome: 'Grêmio', cor: 'Azul e Preto'})
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mvxlgn82xzcqg0x7kqj.png)



# Escolhendo como o nó deve aparecer <a name="como-aparecer">

Nossos nós estão mostrando as informações das cores, mas se eu quiser que apareça o nome do time ao invés das cores?


Clique na label:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvqdvie6vu9rok21f4rr.png)
 
Clique em nome:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbx2t9r07uiwzrcbbqzf.png)

Você pode trocar a cor e o tamanho do nó:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydgqn4ru4uohclyemcfw.png)  

 

# Usando o comando WHERE <a name="comando-where"> 

Antes de usarmos o comando WHERE vamos vizualizar todos os dados:

```cypher
MATCH (n) RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chyjju05u5o1bjxz6ckc.png)
 
#### Filtrando por id:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ywytn82hg90spmmhln9o.png)

```cypher
MATCH (n) WHERE id(n) = 6 RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8dipe1bgw04a7hxz9gya.png)


#### Filtrando por label:

```cypher
MATCH (n :Time) RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yomgkke6f654jjyi0sn.png)

 
```cypher
MATCH (n :Time :Futebol) RETURN n
```
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wub70enjvxta691ho8mj.png)


#### Filtrando por propriedade:

Somente o id, criado automaticamente pelo Neo4j, será buscado com parenteses `id()`; as outras propriedades será por notação de ponto.

```cypher
MATCH (n) WHERE n.nome = 'Internacional' RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yl6lxqt2dhswwufk6zc.png)

 
#### Filtrando por label e propriedade:
```cypher
MATCH (n :Time :Futebol) WHERE n.nome = 'Internacional' RETURN n
```
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44xsbo1n90crkqmjawk3.png)
 
#### Filtrando dois nós:

```cypher
MATCH (i),(g) WHERE i.nome = 'Internacional' AND g.nome = 'Grêmio' RETURN i, g
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gulswr5tkvgghwfnm5u0.png)

ou com label:

```cypher
MATCH (i :Time),(g :Futebol) WHERE i.nome = 'Internacional' AND g.nome = 'Grêmio' RETURN i, g
```
 


# Criando nós estruturados <a name="criando-nos-estruturados">

Primeiramente vamos apagar todos os dados com o comando de deleção que adicionamos nos favoritos.

#### Criando seleções de futebol

```cypher
CREATE (:Selecao {nome: 'Brasil', cor: 'Verde, Amarelo'})

CREATE (:Selecao {nome: 'Argentina', cor: 'Azul, Branco'})

CREATE (:Selecao {nome: 'Uruguai', cor: 'Azul, Branco'})

CREATE (:Selecao {nome: 'Franca', cor: 'Azul, Branco, Vermelho'})

CREATE (:Selecao {nome: 'Espanha', cor: 'Amarelo, Vermelho'})

CREATE (:Selecao {nome: 'Alemanha', cor: 'Amarelo, Vermelho, Preto'})

CREATE (:Selecao {nome: 'Inglaterra', cor: 'Vermelho, Branco'})

CREATE (:Selecao {nome: 'Italia', cor: 'Verde, Vermelho, Branco'})

CREATE (:Selecao {nome: 'EUA', cor: 'Azul, Vermelho, Branco'})

CREATE (:Selecao {nome: 'Japao', cor: 'Vermelho, Branco'})

CREATE (:Selecao {nome: 'Nigeria', cor: 'Verde, Branco'})

CREATE (:Selecao {nome: 'Canada', cor: 'Vermelho, Branco'})

CREATE (:Selecao {nome: 'Colombia', cor: 'Amarelo, Vermelho, Azul'})
```

#### Criando continentes

```cypher
CREATE (:Continente {nome: 'America do Sul'})

CREATE (:Continente {nome: 'America do Norte'})

CREATE (:Continente {nome: 'Europa'})

CREATE (:Continente {nome: 'Africa'})

CREATE (:Continente {nome: 'Asia'})
```

# Usando o comando CONTAINS <a name="comando-contains">

No comando abaixo trazemos todas as seleções que contém as cores vermelho e branco:

```cypher
MATCH (n) WHERE n.cor CONTAINS 'Vermelho' AND n.cor CONTAINS 'Branco' RETURN n
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/07xprvu1np44xo1mo7qs.png)
 

# Criando relacionamentos (arestas) <a name="criando-relacionamentos">

Vamos criar um relacionamento entre `Brasil` e `América de Sul`.
```cypher
MATCH (s :Selecao),(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
RETURN s, c
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/901bg88wf4qmmad77s3g.png)

Criando o relacionamnto `Brasil pertence a América do Sul`:

```cypher
MATCH (s :Selecao),(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
CREATE (s)-[r : Pertence]->(c)
RETURN s, c, r
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vgh0fvtr86cs557cu91u.png)
 

# Relacionamento bidirecional <a name="bidirecional">

Como já comentamos, tente evitar o relacionamento bidirecional e **nunca** cria-lo sem uma real necessidade.

```cypher
MATCH (s :Selecao),(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
CREATE (s)<-[r : Contem]-(c)
RETURN s, c, r
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/baokxbk9nlpaxz4waf5h.png)

# Pesquisando relacionamentos <a name="pesquisando-relacionamentos">

#### Sem especificar relacionamentos

Quando fazemos uma consulta e existem relacionamentos, os relacionamentos aparecem automaticamente:

```cypher
MATCH (s :Selecao),(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
RETURN s, c
```
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ukujb1i722r8hehzh7s7.png)
 
#### Especificando relacionamentos

```cypher
MATCH (s :Selecao)-[r :Pertence]->(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
RETURN s, c
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpaavwah51qc3cwy9sea.png)
 
# Apagando relacionamentos (arestas) <a name="apagando-relacionamentos">

Antes de apagar, sempre faça a consulta para se certificar que a informação é realmente a informação que você deseja apagar:

```cypher
MATCH (s :Selecao),(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
RETURN s, c
```

O relacionamento aparece, mas pra podermos apagar o relacionamento precisamos informá-lo na consulta:

```cypher
MATCH (s :Selecao)-[r :Pertence]->(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
DELETE r
RETURN s, c
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xw2ov9jswevuyjtkkit.png)
 
Para apagar o `Contem` é só inverter a direção da seta:

```cypher
MATCH (s :Selecao)<-[r :Contem]-(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
DELETE r
RETURN s, c
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hafnlin55p3101wbhcmh.png)
 
# Usando o comando MERGE <a name="comando-merge">

O comando MERGE funciona parecido com o comando CREATE, porém, ao contrário do CREATE, o MERGE não vai repetir a criação se já existir. Por fazer essa verificação, o MERGE é menos performatico.

No código abaixo apenas trocamos o CREATE pelo MERGE:

```cypher
MATCH (s :Selecao),(c :Continente)
WHERE s.nome = 'Brasil' and c.nome = 'America do Sul'
MERGE (s)-[r : Pertence]->(c)
RETURN s, c, r
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwa14qihz0z6wtwa2wt3.png)


Se rodarmos o mesmo comando, o relacionamento `Pertence` não será criado novamente, ao contrário do comando CREATE que criaria mais um relacionamento chamado `Pertence`. 


# Tarefa <a name="tarefa">

Como tarefa você pode criar os outros relacionamentos. O comando é o mesmo pra todos. Tente criar os comandos de cabeça sem copiar e colar.

1. Faça a pesquisa dos nós que você quer adicionar o relacionamento.
2. Faça a criação do relacionamento usando CREATE ou MERGE.

[![Formação TS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72gnny6fjwnmku1x3rr4.png)](https://go.hotmart.com/H93763859E)