DEV Community

Maiqui Tomé 🇧🇷
Maiqui Tomé 🇧🇷

Posted on • Updated on

🔵SQL X Cypher/Neo4j: quais amigos dos meus amigos são meus inimigos?

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 - 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'})
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
MATCH (naruto :Ninja),(rock :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  rock.name = 'Rock Lee'
CREATE (naruto)-[:FRIEND_OF]->(rock)
RETURN naruto, rock
Enter fullscreen mode Exit fullscreen mode
MATCH (naruto :Ninja),(gaara :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  gaara.name = 'Gaara'
CREATE (naruto)-[:FRIEND_OF]->(gaara)
RETURN naruto, gaara
Enter fullscreen mode Exit fullscreen mode
MATCH (n) RETURN n
Enter fullscreen mode Exit fullscreen mode

Image description

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
Enter fullscreen mode Exit fullscreen mode
MATCH (sakura :Ninja),(rock :Ninja)
WHERE sakura.name = 'Sakura Haruno' AND  rock.name = 'Rock Lee'
CREATE (sakura)-[:FRIEND_OF]->(rock)
RETURN sakura, rock
Enter fullscreen mode Exit fullscreen mode
MATCH (n) RETURN n
Enter fullscreen mode Exit fullscreen mode

Image description

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
Enter fullscreen mode Exit fullscreen mode
MATCH (naruto :Ninja),(orochimaru :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  orochimaru.name = 'Orochimaru'
CREATE (naruto)-[:ENEMY_OF]->(orochimaru)
RETURN naruto, orochimaru
Enter fullscreen mode Exit fullscreen mode
MATCH (n) RETURN n
Enter fullscreen mode Exit fullscreen mode

Image description

Neo4j - Fazendo a consulta

Amigos do Naruto:

MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
RETURN friends
Enter fullscreen mode Exit fullscreen mode

Image description

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
Enter fullscreen mode Exit fullscreen mode

Image description

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
Enter fullscreen mode Exit fullscreen mode

Image description

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Image description

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;
Enter fullscreen mode Exit fullscreen mode

Image description

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
);
Enter fullscreen mode Exit fullscreen mode

Image description

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
    )
);
Enter fullscreen mode Exit fullscreen mode

Image description

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 :)

Discussion (0)