// NMEC: 104063


//1. Encontre todos os atores que dirigiram um filme em que também atuaram e apresente o nome do ator e o título do filme.
#1
MATCH (p:Person)-[:DIRECTED]->(m:Movie)<-[:ACTED_IN]-(p)
RETURN p.name AS ator, m.title AS filme;



//2. Para cada filme realizado depois de 2005, apresente os nomes de todos os atores que atuaram nesse filme. 
#2
MATCH (m:Movie), (p:Person)
WHERE m.released > 2005 AND (p)-[:ACTED_IN]->(m)
RETURN m.title AS filme, COLLECT(p.name) AS atores
ORDER BY filme;


//!3. Encontre pares de nós com mais do que uma relação entre si.
#3
MATCH (a)-[r]->(b)
WITH a, b, COUNT(r) AS c
WHERE c > 1
RETURN a, b, c
ORDER BY c DESC;


//4. Encontre todos os pares de pessoas que fizeram revisões do mesmo filme. Apresente os seus nomes e título de cada filme
#4
MATCH (p1:Person)-[:REVIEWED]->(m:Movie)<-[:REVIEWED]-(p2:Person)
WHERE p1 <> p2
RETURN p1.name AS pessoa1, p2.name AS pessoa2, m.title AS filme;



//5. Encontre todos os pares de atores que atuaram em vários filmes juntos.
#5
MATCH (p1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
WHERE p1 <> p2
WITH p1, p2, COUNT(m) AS numFilmes
WHERE numFilmes > 1
RETURN p1.name AS ator1, p2.name AS ator2, numFilmes;



//6. Determine a idade média do elenco do filme "Apollo 13" no ano do lançamento do filme.
#6
MATCH (p:Person)-[:ACTED_IN]->(m:Movie {title:"Apollo 13"})
RETURN AVG(m.released - p.born) AS idadeMediaElenco;



//7. Encontre os 10 filmes com o elenco mais velho no momento do lançamento do filme. Apresente o filme e a idade média arredondada a 2 casas decimais, por ordem decrescente.
#7
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH m, AVG(m.released - p.born) AS idadeMedia
ORDER BY idadeMedia DESC
LIMIT 10
RETURN m.title AS filme, ROUND(idadeMedia, 2) AS idadeMediaElenco;



//8. Apresente o subgrafo ACTED_IN do filme com o elenco mais novo, no momento do lançamento do filme
#8
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH m, AVG(m.released - p.born) AS idadeMedia
ORDER BY idadeMedia ASC
LIMIT 1
MATCH (p:Person)-[r:ACTED_IN]->(m)
RETURN p, r, m;



//!!9. Qual é o caminho mais curto (usando qualquer tipo de relação) entre John Cusack e Demi Moore?
#9
MATCH (p1:Person {name:"John Cusack"}), (p2:Person {name:"Demi Moore"}),
path = shortestPath((p1)-[*]-(p2))
RETURN path;



//!!10. Qual a dimensão caminho mais curto (usando qualquer tipo de relação) entre Keanu Reeves e Tom Cruise?
#10
MATCH (p1:Person {name:"Keanu Reeves"}), (p2:Person {name:"Tom Cruise"}),
path = shortestPath((p1)-[*]-(p2))
RETURN length(path) AS tamanhoCaminho;



//!!11. Quais são as dimensões do caminho mais curto entre pessoas com nome Jim e pessoas com nome Kevin?
#11
MATCH (j:Person), (k:Person)
WHERE j.name STARTS WITH "Jim" 
  AND k.name STARTS WITH "Kevin"
  AND j <> k
WITH j, k, shortestPath((j)-[*]-(k)) AS sp
WHERE sp IS NOT NULL
RETURN j.name AS nomej, k.name AS nomek, length(sp) AS distancia
ORDER BY distancia;


// (a distância entre duas pessoas é o comprimento do caminho mais curto entre eles)
//12. Que pessoas têm uma distância 2 para Jim Cash?
#12
MATCH (j:Person {name:"Jim Cash"}), (p:Person)
WHERE j <> p
WITH j, p, shortestPath((j)-[*]-(p)) AS sp
WHERE length(sp) = 2
RETURN p.name AS pessoa;



//13. Qual é a maior distância de uma pessoa para Kevin Bacon?
#13
MATCH (p1:Person {name:"Kevin Bacon"}), (p2:Person)
WHERE p1 <> p2
WITH p2, shortestPath((p1)-[*]-(p2)) AS sp
WHERE sp IS NOT NULL
RETURN p2.name AS pessoa, length(sp) AS distancia
ORDER BY distancia DESC
LIMIT 1;



//14. Qual é a maior distância entre duas pessoas?
#14
MATCH (p1:Person), (p2:Person)
WHERE p1 <> p2
WITH shortestPath((p1)-[*]-(p2)) AS sp
WHERE sp IS NOT NULL
RETURN length(sp) AS distancia
ORDER BY distancia DESC
LIMIT 1;


//!!15. Qual é a distribuição de distâncias em pares (isto é, para a distância 1, 2, 3, ..., quantos pares de pessoas têm essa distância um do outro)?
#15
MATCH (p1:Person), (p2:Person)
WHERE p1 <> p2 AND id(p1) < id(p2)
WITH shortestPath((p1)-[*]-(p2)) AS sp
WHERE sp IS NOT NULL
RETURN length(sp) AS distancia, COUNT(*) AS numPares
ORDER BY distancia;



//!!16. Indique as 10 pessoas com menor distância média em que o caminho entre elas são relações do tipo ACTED_IN.
#16
MATCH (p1:Person)
WITH COLLECT(p) AS pessoas
UNWIND pessoas AS p
MATCH (p2:Person)
WHERE p1 <> p2
MATCH path = shortestPath((p1)-[:ACTED_IN*]-(p2))
WITH p1, p2, path
WITH p1, AVG(length(path)) AS distMedia
ORDER BY distMedia ASC
LIMIT 10
RETURN p1.name AS pessoa, distMedia;



//17. Apresente os atores que tiveram pelo menos uma role para personagens com o prefixo 'Dr.'. O resultado deve ser uma lista com o par “Ator, Lista das roles”
#17
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
WHERE ANY(role IN r.roles WHERE role STARTS WITH "Dr.")
WITH p, COLLECT([role IN r.roles WHERE role STARTS WITH "Dr."]) AS rolesDr
RETURN p.name AS ator, APOC.COLL.FLATTEN(rolesDr) AS roles;



//------------------
//Crie 3 novas perguntas adicionais à base dados e apresente igualmente a solução de pesquisa para cada questão.


//18. Apresente as 5 pessoas que avaliaram mais filmes e apresente o seu nome e o numero de avaliacoes.
#18
MATCH (p:Person)-[r:REVIEWED]->(m:Movie)
WITH p, COUNT(r) AS numReviews
ORDER BY numReviews DESC
LIMIT 5
RETURN p.name AS pessoa, numReviews AS numeroDeReviews;



//19. Indique os atores que atuaram com o maior numero de outros atores. Apresente o nome do ator e o numero total de colaboracoes unicas.
#19
MATCH (p1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
WHERE p1 <> p2
WITH p1, COUNT(DISTINCT p2) AS numColaboracoes
ORDER BY numColaboracoes DESC
RETURN p1.name AS ator, numColaboracoes;



//20. Encontre os pares de atores que atuaram juntos no mesmo filme e possuem a maior diferença de idades
#20
MATCH (p1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
WHERE p1 <> p2
WITH p1, p2, m, (m.released - p1.born) AS idadeP1, (m.released - p2.born) AS idadeP2
WITH p1, p2, m, ABS(idadeP1 - idadeP2) AS diferenca
ORDER BY diferenca DESC
RETURN p1.name AS ator1, p2.name AS ator2, m.title AS filme, diferenca AS diferencaIdade;
