Bases de Données / Databases

Site Web de l'équipe BD du LIP6 / LIP6 DB Web Site

Outils pour utilisateurs

Outils du site


site:enseignement:master:bdle:tmes:graphes-neo4j

Ceci est une ancienne révision du document !


Calculs sur les graphes en Neo4J

Le graphe qui sera utilisé pendant le TME représente des personnages de la bande dessinée “Asterix” avec les albums dans lesquels ils apparaissent. Les commandes de création de ce graphe se trouvent dans ce fichier à télécharger,source.

Création du graphe

Créer et visualiser le graphe en copiant dans la ligne de commande les instructions présentes dans le fichier

Interrogation

Écrire les requêtes suivantes:

Q1) Visualiser le graphe (afficher tous les noeuds et tous les arcs). Quelles sont les propriétés et les étiquettes des noeuds et des arcs?

Réponse

match (n)-[r]->(m)
return n, r, m

Q2) Ajouter une étiquette :PERSONNAGE aux noeuds qui ont une propriété “personnageid”

Réponse


Q3) Compter le nombre de noeuds

Réponse

Match (n)
return count(n)

Q4) Compter le nombre d'arcs

Réponse

match (n)-[r]->()
return count(r)
Résultat: 67

Q5) Trouver l'étiquette do noeud dont le nom est 'Jules Cesar'

Réponse

match (n)
where n.name = 'Jules Cesar'
return labels(n)
Résultat: ["PERSONNAGE"]│

Q6) Trouver l'étiquette des arcs vers le noeud dont le nom est 'Le Domaine des dieux'

Réponse

match (n {name: 'Le Domaine des dieux'})<-[r]-()
return distinct type(r)
Réponse: APPARAIT_DANS
!! Attention à la casse pour name

Q7) Afficher toutes les propriétés des trois noeuds parmi les noeuds de type PERSONNAGE:

Réponse

match (n:PERSONNAGE)
return * limit 3

{"nationalite":"Egyptienne","personnageid":56,"personnagetype":"Les au│
│tres","name":"Cleopatre"}                                             │
├──────────────────────────────────────────────────────────────────────┤
│{"personnageid":44,"nationalite":"Romain/Egyptien","personnagetype":"L│
│es autres","name":"Cesarion (Ptolemee XVI)"}                          │
├──────────────────────────────────────────────────────────────────────┤
│{"nationalite":"Romain","personnageid":91,"personnagetype":"Les Romain│
│s","name":"Jules Cesar"}  

Q8) Afficher les noms des personnages qui n'ont pas d'arc sortant de type COMPAGNON_AVENTURE:

Réponse

match (n:PERSONNAGE)-[r:COMPAGNON_AVENTURE]->(p)
where NOT (p)-[:COMPAGNON_AVENTURE]->()
return distinct p.name

!!NOT (p)-[r:COMPAGNON_AVENTURE]->() ne marche pas
——————————
ou: 
match (p:PERSONNAGE)
where NOT (p)-[:COMPAGNON_AVENTURE]->()
return distinct p.name


Résultat: "Cesarion (Ptolemee XVI)"
"Numerobis"
"Brutus"
"Lupus"
"Epidemais"
"Assurancetourix"
"Briseradius"

Q9)Afficher deux triangles (on considère le graphe comme étant non-dirigé)

Réponse

Match (a)--(b)--(c)--(a)
return distinct a, b, c
limit 2

Q10) Afficher les noms des trois couples de personnages qui apparaissent dans le même album, ainsi que l'id de album commun

Réponse

match (p1)-[:APPARAIT_DANS]->(m), (p2)-[:APPARAIT_DANS]->(m)
where p1 <> p2 
return distinct p1.name, p2.name,  m.albumid limit 3

Résultat: 
"Cleopatre"│"Numerobis"  │6          │
├───────────┼─────────────┼───────────┤
│"Cleopatre"│"Jules Cesar"│6          │
├───────────┼─────────────┼───────────┤
│"Cleopatre"│"Numerobis"  │34   

Q11) Afficher pour chaque couple de personnages reliés par un arc (non-dirigé) de type COMPAGNON_AVENTURE le nombre d'albums qu'ils ont en commun (afficher le triplet contenant les noms des personnages et le nombre d'albums en commun). Chaque couple de personnages doit apparaître une seule fois. Trier par nombre total d'albums décroissant.

Réponse

match (n)-[r:APPARAIT_DANS]->(a)<-[:APPARAIT_DANS]-(m),
(n)-[t:COMPAGNON_AVENTURE]-(m)
where n.name < m.name
return distinct n.name, m.name,  count(distinct r) as total
order by total desc

Résultat: 
"Cleopatre"	"Jules Cesar"	3
"Cleopatre"	"Numerobis"	2
"Caius Obtus"	"Jules Cesar"	1
"Caligula Alavacomgetepus"	"Jules Cesar"	1
"Cesarion (Ptolemee XVI)"	"Cleopatre"	1

Q12) Modifier la requête précédente afin d'ajouter à l'arc de type COMPAGNON_AVENTURE qui relie les personnages une propriété 'albums' dont la valeur est le nombre total d'albums en commun.

Réponse

match (n)-[r:APPARAIT_DANS]->(a)<-[:APPARAIT_DANS]-(m),
(n)-[t:COMPAGNON_AVENTURE]-(m)
where n.name < m.name
with n, m, t, count(distinct r) as total
set t.albums = total
return distinct n.name, m.name, t.albums

Q13) Afficher pour chaque noeud son nom et son le degré. Ordonner par ordre croissant des degrés. Considérer uniquement les arcs de type NATIONALITE et PERSONNAGE_TYPE.

Réponse

match (n)-[r:NATIONALITE|:PERSONNAGE_TYPE]-()
return n.name, count(distinct r) as degree
order by degree

Q14) Degré total des noeuds

  1. Afficher pour chaque valeur de degré le nombre de noeuds avec ce degré. Considérer tous les arcs, ordonner par degré.
  2. Pour chaque noeud enregistrer son degré somme nouvelle propriété.

Réponse

match (n)-[r]-()
with n as nodes, count(distinct r) as degree
return degree, count(nodes) order by degree asc

match (n)-[r]-()
with n, count(distinct r) as degree
set n.deg = degree
return n.name, n.deg

Q15) Afficher pour chaque noeud son nom et son degré sortant. Pour les noeuds sans liens sortants afficher 0. Ordonner par ordre décroissant des degrés. Considérer uniquement les arcs de type NATIONALITE et PERSONNAGE_TYPE.

Réponse

match (n)-[r:NATIONALITE|:PERSONNAGE_TYPE]->()
return distinct n.name as Node, count(r) as Outdegree
order by Outdegree

union

match (a)-[r:NATIONALITE|:PERSONNAGE_TYPE]->(b)
where not((b)-[:COMPAGNON_AVENTURE]->())
return distinct b.name as Node, 0 as Outdegree

Q16) Afficher le sous-graphe contenant comme noeuds source 'Cleopatre', 'Jules Cesar' ou 'Caius Obtus' et comme noeuds destination 'Cesarion (Ptolemee XVI)' ou 'Caligula Alavacomgetepus'. Les noeuds sont reliés par des arcs de type COMPAGNON_AVENTURE.

Réponse

match (n)-[:COMPAGNON_AVENTURE]-(m)
where n.name in ['Cleopatre', 'Jules Cesar', 'Caius Obtus'] and m.name in [ 'Cesarion (Ptolemee XVI)', 'Caligula Alavacomgetepus']
return distinct n.personnageid, m.personnageid

Résultat:
════════════════╪════════════════╡
│56              │44              │
├────────────────┼────────────────┤
│91              │44              │
├────────────────┼────────────────┤
│91              │38              │
└────────────────┴────────────────┘

Q17) Afficher le sous-graphe des personnages reliés par des arcs de type COMPAGNON_AVENTURE qui ne contient pas 'Cleopatre':

Réponse

match (n)-[r:COMPAGNON_AVENTURE]->(m)
where n.name <> 'Cleopatre' and m.name <> 'Cleopatre'
return n, m

Q18) Afficher le sous-graphe contenant les noeuds qui se trouvent à une distance 3 de 'Cleopatre' ainsi que les arcs de type COMPAGNON_AVENTURE qui les relient. On considère uniquement les arcs dirigés de type COMPAGNON_AVENTURE.

Réponse

match p=(a)-[:COMPAGNON_AVENTURE*3..3]->(b)
where a.name='Cleopatre'
return p

Q19) Afficher le plus court chemin et sa longueur entre Jules Cesar et Epidemais.

Réponse

match p=shortestPath((a)-[:COMPAGNON_AVENTURE*1..10]->(c))
where  a.name='Jules Cesar' and c.name='Epidemais'
return p, length(p) 

Q20) Afficher le plus long chemin de type COMPAGNON_AVENTURE et sa longueur entre Jules Cesar et Brutus (graphe non-dirigé).

Réponse

match p=(a)-[:COMPAGNON_AVENTURE*]->(c)
where a.name='Jules Cesar' and c.name='Brutus'
return p, length(p) 
order by length(p) desc Limit 1

Q21) Afficher les noms des personnages sur le plus court chemin de type COMPAGNON_AVENTURE entre Numerobis et Assurancetourix (utiliser la fonction EXTRACT) (graphe non-dirigé).

Réponse

match p=shortestPath((a)-[:COMPAGNON_AVENTURE*1..10]-(c))
where  a.name='Numerobis' and c.name='Assurancetourix'
RETURN EXTRACT(n IN NODES(p)| n.name) AS Paths

Résultat: 
["Numerobis", "Cleopatre", "Jules Cesar", "Caligula Alavacomgetepus", "Assurancetourix"]

Q22) Afficher le diamètre du graphe en considérant uniquement les noeuds de type PERSONNAGE et les arcs de type COMPAGNON_AVENTURE

Réponse

match (n:PERSONNAGE), (m:PERSONNAGE)
where n <> m
with n, m
match p=shortestPath((n)-[:COMPAGNON_AVENTURE*]->(m))
return n.name, m.name, length(p)
order by length(p) desc limit 1

q) Afficher les noms des noeuds sur tous les plus courts chemins entre Numerobis et Assurancetourix. Afficher uniquement les plus courts chemins contenant plus de 4 noeuds (utiliser la fonction EXTRACT)(graphe non-dirigé).

Réponse

MATCH p = allShortestPaths((Source)-[:COMPAGNON_AVENTURE*]-(destination))
WHERE source.name='Numerobis' AND destination.name = 'Assurancetourix' AND LENGTH(NODES(p)) > 4
RETURN distinct EXTRACT(n IN NODES(p)| n.name) AS Paths,length(p)

Réponse: 

["Numerobis", "Cleopatre", "Jules Cesar", "Caligula Alavacomgetepus", "Assurancetourix"]	4
["Numerobis", "Cleopatre", "Jules Cesar", "Caius Obtus", "Assurancetourix"]	4

q) On considère la propriété 'albums' des arcs de type COMPAGNON_AVENTURE comme poids des arcs. Afficher le chemin avec la distance la plus courte entre Numerobis et Assurancetourix qui considère ces poids (même résultat que celui obtenu avec l'algorithme de Dijkstra). Considérer uniquement les arcs de type COMPAGNON_AVENTURE et leur poids (aide (utiliser REDUCE): REDUCE(dist = 0, rel in rels(path) | dist+rel.albums)).

Réponse

MATCH (from: PERSONNAGE {name:'Numerobis'}), (to: PERSONNAGE {name:'Assurancetourix'}),
path = shortestPath((from)-[:COMPAGNON_AVENTURE*1..10]->(to))
WITH REDUCE(dist = 0, rel in rels(path) | dist+rel.albums) AS distance, path
RETURN path, distance

q) Effacer tous les noeuds et leur arcs

Réponse

Match(n)-[r]-() 
delete n, r

q) Effacer tous les nodes qui n'ont pas d'arcs

Réponse

match (n) delete n
site/enseignement/master/bdle/tmes/graphes-neo4j.1516880050.txt.gz · Dernière modification: 25/01/2018 12:34 par camelia