Modèle de données
Description des entités
User : décrit un utilisateur de la base de données MovieLens ; contient les attributs suivants :
Valeur | Type |
---|---|
id | int |
sex | string |
age | int |
occupation | Str |
zipcode | int |
Movie : représente un film de la base de données
MovieLens contient les attributs suivants :
Valeur | Type |
---|---|
id | int |
title | string |
date | int |
Genre : fait référence au genre d’un film ; contient les attributs suivants :
Valeur | Type |
---|---|
id | int |
name | string |
Description des relations
- RATED : spécifie la note qu’a laissée un utilisateur à propos d'un film ; contient les attributs suivants :
Valeur | Type |
---|---|
note | int |
timestamp | int |
FRIEND_OF: représente un lien d’amitié entre deux
utilisateurs
notez que, comme toutes les relations
dans Neo4j, celle-ci est orientée mais elle est
également symétrique dans ce jeu de données (c'est-à-dire que si A est ami avec B, alors B est ami avec A).CATEGORIZED_AS : permet d’assigner un genre à un
film
Modélisation graphe
On représente les informations dans un graphe ayant la forme suivante:
Note: On laisse de côté certains attributs à des fins de clarté
Ou en syntaxe CYPHER
(:User{name})-[:FRIEND_OF]-(:User{name})
(:User{name})-[:RATED{note, timestamp}]->(:Movie{title,released})
(:Movie{title,released})-[:CATEGORIZED_AS]->(:Genre{name})
Importation des données en base
Import des genres
LOAD CSV WITH HEADERS FROM "file:///genres.csv" as
line CREATE (g:Genre { id: toInt(line.id), name:line.name} )
Import des films
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///movies.csv" AS movies
CREATE (m:Movie {id : toInt(movies.id), title : movies.title, date : toInt(movies.date)});
Import des utilisateurs
LOAD CSV WITH HEADERS FROM "file:///users.csv" as
line CREATE (g:User { id: toInt(line.id), age: toInt(line.age), sex: line.sex, occupation:line.occupation, zipcode:line.zipcode} )
Note: on conserve le ZIPCODE sous forme textuelle
Import des catégories
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///mov_genre.csv" AS line
MATCH (m:Movie {id:toInt(line.mov_id)})
MATCH (g:Genre {id:toInt(line.genre)})
CREATE (m)-[:CATEGORIZED_AS]->(g);
Import des ratings
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///ratings.csv" AS line
MATCH (m:Movie {id:toInt(line.mov_id)})
MATCH (u:User {id:toInt(line.user_id)})
CREATE (u)-[:RATED{note: toInt(line.rating), timestamp: toInt(line.timestamp)}]->(m);
Import des friends_of
Toutes les relations sont orientées en Neo4J.
La relation "Friend_Of" est bidirectionnelle.
Nous faisons le choix de choisir un sens arbitraire:
(a)-[:FRIEND_OF]->(b)
et nous utiliserons un sens "non orienté" pour les requêtes
MATCH (a)-[:FRIEND_OF]-(b)
Code d'import
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///friends.csv" AS line
MATCH (u1:User {id:toInt(line.user1_id)})
MATCH (u2:User {id:toInt(line.user2_id)})
MERGE (u1)-[:FRIEND_OF]-(u2);
Les requêtes
Question 1. Combien y a-t-il d’utilisateurs dans la base de données ?
MATCH (:User)
RETURN count(*)
Question 2. Quel est l’âge et le sexe de l’utilisateur qui a pour id la valeur 1
MATCH (u:User{id:1})
RETURN u.age, u.sex
Question 3.1. Quelles sont les femmes qui sont artistes (artist) ?
MATCH (_:User{sex:'F', occupation:'artist'})
RETURN *
Question 3.2. Quelles sont les femmes qui sont artistes (artist) ou auteurs (writer) ?
MATCH (u:User{sex:'F'})
WHERE u.occupation IN ["artist", "writer"]
RETURN u
Question 4. Quel est l’âge moyen des étudiants de la base de données ?
MATCH (u:User)
RETURN avg(u.age)
Question 5. Quel est l’âge moyen des utilisateurs pour chaque occupation?
MATCH (u:User)
RETURN u.occupation, avg(u.age)
ORDER BY avg(u.age) ASC
Question 6.1. Quel est le nombre d’utilisateurs pour chaque occupation ?
MATCH (u:User)
RETURN u.occupation, count(*)
Question 6.2. Quelles sont les 5 occupations les plus populaires ?
MATCH (u:User)
RETURN u.occupation, count(*) AS effectif
ORDER BY effectif DESC
LIMIT 5
Question 7. Combien y a-t-il d’occupations différentes dans le jeu de données ?
MATCH (u:User)
RETURN count(DISTINCT u.occupation)
Question 8. Quels sont les films qui ont la note moyenne maximale (note = 5) ?
MATCH ()-[r:RATED]-(m:Movie)
WITH m.title as Film_5_étoiles, avg(r.note) as Score
WHERE Score = 5
RETURN Film_5_étoiles
Question 9. Qui sont les amis et les amis des amis de l’utilisateur qui a pour id la valeur 1 ? La requête ne doit pas retourner l’utilisateur 1 dans la liste de résultats.
On parcours le graphe des relations depuis le noeud "User 1" de façon non orientée ( -[]- ) avec une limite de 2 arcs maximum.
MATCH (:User{id:1})-[r:FRIEND_OF*1..2]-(u:User)
RETURN DISTINCT u
Question 10. Qui sont les amis et les amis des amis de l’utilisateur qui a pour id la valeur 1, et leur degrés de séparation (nombre de relations FRIEND_OF qui les séparent)?
MATCH p=(:User{id:1})-[r:FRIEND_OF*1..2]-(u:User)
RETURN DISTINCT u, length(p)
Question 11. Quel est l’utilisateur qui a le plus d’amis en commun avec l’utilisateur 1 ?
On recherche les amis de $User_1$:
MATCH (:User{id:1})--(friends:User)
RETURN collect(friends.id)
id=[136,112,162]
Quels sont les utilisateurs ayant le plus d'amis en commun (max 3)
MATCH p=(i:User{id:1})--(common_friend:User)--(u2:User), (u2)--(common_friends) RETURN u2, count(*) as Nb_in_common ORDER BY Nb_in_common DESC
MATCH p=(i:User{id:1})--(common_friend:User)--(u2:User) RETURN u2.id, common_friend.id, count(*) as Nb_in_common ORDER BY u2.id DESC
Question 12. Quel est l’utilisateur qui a le plus d’amis en commun avec l’utilisateur 1 mais qui n’est pas déjà son ami ?
Question 13. Quel est l’utilisateur qui a noté le plus grand nombre de films parmi ceux que l’utilisateur 1 a notés, et quel est ce nombre ?
Question 14. Quel est l’utilisateur qui a noté le plus grand nombre de films parmi ceux que l’utilisateur 1 a notés, et quel est ce nombre ?
Question 15 Recommander quelques films à l’utilisateur 1 en fonction des préférences de ses amis
Question 16 Recommander quelques films à l’utilisateur 1 en fonction de ce qu’il a aimé dans le passé
Les Questions BONUS!!!
Question 17. Quels sont les films dont la note moyenne dépasse 4.
MATCH ()-[r:RATED]-(m:Movie)
WITH m.title as Film, avg(r.note) as Score
WHERE Score > 4
RETURN Film, Score ORDER BY Score DESC
Question 18. à Question 23:
Répétition des questions 8 à 13