Neste post vamos comparar uma consulta feita com SQL e a mesma consulta feita com CYPHER; linguagem do Neo4j. Vamos pesquisar quais amigos dos meus amigos são meus inimigos. Vamos usar os personagens do anime Naruto.
- Neo4j
- SQL
- Conclusão
Neo4j - Criando os personagens
CREATE (:Ninja {name: 'Naruto Uzumaki'})
CREATE (:Ninja {name: 'Sasuke Uchiha'})
CREATE (:Ninja {name: 'Sakura Haruno'})
CREATE (:Ninja {name: 'Gaara'})
CREATE (:Ninja {name: 'Rock Lee'})
CREATE (:Ninja {name: 'Orochimaru'})
Neo4j - Criando relacionamentos de amizade
Amigos do Naruto:
MATCH (naruto :Ninja),(sakura :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND sakura.name = 'Sakura Haruno'
CREATE (naruto)-[:FRIEND_OF]->(sakura)
RETURN naruto, sakura
MATCH (naruto :Ninja),(rock :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND rock.name = 'Rock Lee'
CREATE (naruto)-[:FRIEND_OF]->(rock)
RETURN naruto, rock
MATCH (naruto :Ninja),(gaara :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND gaara.name = 'Gaara'
CREATE (naruto)-[:FRIEND_OF]->(gaara)
RETURN naruto, gaara
MATCH (n) RETURN n
Amigos da Sakura:
MATCH (sakura :Ninja),(sasuke :Ninja)
WHERE sakura.name = 'Sakura Haruno' AND sasuke.name = 'Sasuke Uchiha'
CREATE (sakura)-[:FRIEND_OF]->(sasuke)
RETURN sakura, sasuke
MATCH (sakura :Ninja),(rock :Ninja)
WHERE sakura.name = 'Sakura Haruno' AND rock.name = 'Rock Lee'
CREATE (sakura)-[:FRIEND_OF]->(rock)
RETURN sakura, rock
MATCH (n) RETURN n
Neo4j - Criando relacionamentos de inimizade
Inimigos do Naruto:
MATCH (naruto :Ninja),(sasuke :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND sasuke.name = 'Sasuke Uchiha'
CREATE (naruto)-[:ENEMY_OF]->(sasuke)
RETURN naruto, sasuke
MATCH (naruto :Ninja),(orochimaru :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND orochimaru.name = 'Orochimaru'
CREATE (naruto)-[:ENEMY_OF]->(orochimaru)
RETURN naruto, orochimaru
MATCH (n) RETURN n
Neo4j - Fazendo a consulta
Amigos do Naruto:
MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
RETURN friends
Amigos dos amigos do Naruto:
MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
MATCH (friends)-[:FRIEND_OF]->(friends_of_friends)
RETURN friends_of_friends
Amigos dos amigos do Naruto que são inimigos do Naruto:
MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
MATCH (friends)-[:FRIEND_OF]->(friends_of_friends)
MATCH (naruto)-[:ENEMY_OF]->(friends_of_friends)
RETURN naruto,friends_of_friends
SQL - Criando os personagens
CREATE TABLE ninjas(
id SERIAL PRIMARY KEY,
name VARCHAR(255)
);
INSERT INTO
ninjas (name)
VALUES
('Naruto Uzumaki'),
('Sasuke Uchiha'),
('Sakura Haruno'),
('Gaara'),
('Rock Lee'),
('Orochimaru');
SELECT * FROM ninjas;
SQL - Criando relacionamentos de amizade
CREATE TABLE friends(
id SERIAL PRIMARY KEY,
ninja_1 INTEGER,
ninja_2 INTEGER,
FOREIGN KEY (ninja_1) REFERENCES ninjas (id),
FOREIGN KEY (ninja_2) REFERENCES ninjas (id),
UNIQUE(ninja_1, ninja_2)
);
-- Amigos do Naruto:
INSERT INTO
friends (ninja_1, ninja_2)
VALUES
(1, 3),
(1, 4),
(1, 5);
-- Amigos da Sakura:
INSERT INTO
friends (ninja_1, ninja_2)
VALUES
(3, 2),
(3, 5);
SELECT * FROM friends;
SQL - Criando relacionamentos de inimizade
CREATE TABLE enemies(
id SERIAL PRIMARY KEY,
ninja_1 INTEGER,
ninja_2 INTEGER,
FOREIGN KEY (ninja_1) REFERENCES ninjas (id),
FOREIGN KEY (ninja_2) REFERENCES ninjas (id),
UNIQUE(ninja_1, ninja_2)
);
-- Inimigos do Naruto:
INSERT INTO
enemies (ninja_1, ninja_2)
VALUES
(1, 2),
(1, 6);
SELECT * FROM enemies;
SQL - Fazendo a consulta
Amigos do Naruto:
SELECT DISTINCT
f.ninja_2,
(SELECT name FROM ninjas WHERE id = f.ninja_2)
FROM
ninjas n,
friends f
WHERE
f.ninja_1 = 1;
Amigos da Sakura:
SELECT DISTINCT
f.ninja_2,
(SELECT name FROM ninjas WHERE id = f.ninja_2)
FROM
ninjas n,
friends f
WHERE
f.ninja_1 = 3;
Amigos dos amigos do Naruto:
SELECT DISTINCT
f.ninja_2,
(SELECT name FROM ninjas WHERE id = f.ninja_2)
FROM
ninjas n,
friends f
WHERE
f.ninja_1
IN
(
SELECT DISTINCT
f.ninja_2
FROM
ninjas n,
friends f
WHERE
f.ninja_1 = 1
);
Amigos dos amigos do Naruto que são inimigos do Naruto:
SELECT
e.ninja_2,
(SELECT name FROM ninjas WHERE id = e.ninja_2)
FROM
enemies e
WHERE
ninja_2
IN
(
SELECT DISTINCT
f.ninja_2
FROM
ninjas n,
friends f
WHERE
f.ninja_1
IN
(
SELECT DISTINCT
f.ninja_2
FROM
ninjas n,
friends f
WHERE
f.ninja_1 = 1
)
);
Conclusão
Conseguimos concluir que essa consulta é bem mais simples fazer com a linguagem Cypher. Nesses casos é bom usar um banco de dados de grafos como o Neo4j. Se alguém tiver um jeito mais simples de fazer essa consulta com SQL por favor deixe seu comentário :)
Top comments (0)