Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
site:enseignement:master:bdle:tmes:tmejointure [29/11/2018 21:31] hubert [Préparation] |
site:enseignement:master:bdle:tmes:tmejointure [14/12/2018 16:18] (Version actuelle) hubert [Exercice 6 : Chemin le plus long] |
||
---|---|---|---|
Ligne 20: | Ligne 20: | ||
idea.sh & | idea.sh & | ||
</code> | </code> | ||
- | + | Dans IDEA : importer le fichier PartitionEtudiant.scala en tant que script scala dans votre projet courant. Exemple si votre projet s'appelle BDLE : | |
- | Editer le fichier de TME | + | |
<code bash> | <code bash> | ||
- | cd <répertoire de travail> # aller dans votre répertoire de tme | + | cd |
- | cp /Infos/bd/spark/tme-jointure2017-etudiant.scala . | + | cp /Infos/bd/spark/PartitionEtudiant.scala IdeaProjects/BDLE/src/main/scala |
- | emacs tme-jointure2017-etudiant.scala & | + | |
</code> | </code> | ||
+ | |||
Ligne 100: | Ligne 99: | ||
return List(s.toString()).iterator | return List(s.toString()).iterator | ||
} | } | ||
+ | |||
+ | def affichePartitions[T: ClassTag](d: Dataset[T]): Unit = d.rdd.mapPartitionsWithIndex(entete).collect.foreach(println) | ||
+ | |||
// Déterminer le nombre d'éléments contenus dans chaque partition | // Déterminer le nombre d'éléments contenus dans chaque partition | ||
Ligne 111: | Ligne 113: | ||
- | // Supprimer les données persistant en mémoire | + | // Supprimer les collections persistant en mémoire |
- | def cleanStorage() = { | + | def clearStorage() = { |
- | val nbCol = spark.sparkContext.getPersistentRDDs.size | + | spark.catalog.clearCache() |
- | spark.sparkContext.getPersistentRDDs.values.foreach(x => x.unpersist()) | + | |
- | println(s"$nbCol collections removed") | + | |
} | } | ||
Ligne 131: | Ligne 131: | ||
On utilise les données de YAGO du fichier yagoMelange.json. Consulter un extrait des données : | On utilise les données de YAGO du fichier yagoMelange.json. Consulter un extrait des données : | ||
<code bash> | <code bash> | ||
+ | ls -lh /Infos/bd/spark/dataset/yago/yagoMelange*.json | ||
head -n 20 /Infos/bd/spark/dataset/yago/yagoMelange.json | head -n 20 /Infos/bd/spark/dataset/yago/yagoMelange.json | ||
+ | head -n 20 /Infos/bd/spark/dataset/yago/yagoMelange1M.json | ||
</code> | </code> | ||
Ligne 147: | Ligne 149: | ||
<code scala> | <code scala> | ||
- | val yago = spark.read.json("/Infos/bd/spark/dataset/yago/yagoMelange.json"). | + | val yago = spark.read.json("/Infos/bd/spark/dataset/yago/yagoMelange1M.json"). |
select("sujet", "prop", "objet").as[Triplet] | select("sujet", "prop", "objet").as[Triplet] | ||
| | ||
Ligne 177: | Ligne 179: | ||
<code scala> | <code scala> | ||
- | val vit = sc.parallelize(a, 4).map(s=> s.split(" ")).map(t => Triplet(t(0), t(1), t(2))) | + | val vit = spark.sparkContext.parallelize(a, 4).map(s=> s.split(" ")).map(t => Triplet(t(0), t(1), t(2))) |
// afficher les partitions | // afficher les partitions | ||
Ligne 376: | Ligne 378: | ||
) | ) | ||
- | val sport2 = sc.parallelize(sport1, 4).map(s=> s.split(" ")).map(t => Triplet(t(0), t(1), t(2))) | + | val sport2 = spark.sparkContext.parallelize(sport1, 4).map(s=> s.split(" ")).map(t => Triplet(t(0), t(1), t(2))) |
// afficher les partitions | // afficher les partitions | ||
Ligne 440: | Ligne 442: | ||
On partitionne les triplets du dataset YAGO de 3 façons différentes: dans l'ordre du initial fichier, par sujet et par objet. | On partitionne les triplets du dataset YAGO de 3 façons différentes: dans l'ordre du initial fichier, par sujet et par objet. | ||
<code scala> | <code scala> | ||
- | val yagoFile = "/Infos/bd/spark/dataset/yago/yagoMelange.json" | + | val yagoFile = "/Infos/bd/spark/dataset/yago/yagoMelange1M.json" |
val yagoInitial = // à compléter ... | val yagoInitial = // à compléter ... | ||
yagoInitial.persist.count | yagoInitial.persist.count | ||
Ligne 450: | Ligne 452: | ||
yagoParObjet.persist.count | yagoParObjet.persist.count | ||
+ | </code> | ||
+ | Afficher un extrait des données pour les sprinter (les personnes dont le sujet contient sprinter) : | ||
+ | <code scala> | ||
+ | val yagoSprinter = yago.where("sujet like '%(sprinter)%'") | ||
+ | affichePartitions(yagoSprinter) | ||
</code> | </code> | ||
- | Afficher un extrait des données pour les sprinters (les personnes dont le sujet contient sprinter) : | + | Est-ce que tous les triplets au sujet du sprinter Percy_Williams sont dans la même partition ? |
+ | Combien de partitions faut-il lire pour trouver le genre et les nationalités de Percy_Williams ? | ||
<code scala> | <code scala> | ||
- | val yagoSprinter = yago.where("sujet like '<%sprinter%>'") | + | val percy = yago.where("sujet = '<Percy_Williams_(sprinter)>' ") |
- | yagoSprinter.rdd.mapPartitionsWithIndex(entete).take(8).foreach(println) | + | affichePartitions(percy) |
</code> | </code> | ||
- | Est-ce que tous les triplets au sujet du sprinter //Aaron Brown// sont dans la même partition ? Si oui, quel est son numéro de partition ? | + | /** |
- | Combien de partitions faut-il lire pour trouver la résidence et la nationalité d'Aaron Brown ? | + | sprinter Aaron Brown |
+ | val yagoSheela = yago.where("sujet like '%<Sheela>'") | ||
+ | */ | ||
Remarque concernant le renommage d'attributs dans une requête de jointure. | Remarque concernant le renommage d'attributs dans une requête de jointure. | ||
Ligne 635: | Ligne 645: | ||
- | === Equi-jointure lorsque les attribut n'ont pas le même domaine === | + | === Equi-jointure lorsque les attributs n'ont pas le même domaine === |
Soit la requête R5 | Soit la requête R5 | ||
Ligne 687: | Ligne 697: | ||
===== Exercice 4 : Produit Cartésien ===== | ===== Exercice 4 : Produit Cartésien ===== | ||
- | Voir diapo 33: Calculer la similarité entre 2 utilisateurs de MovieLens (ou 2 personnes de Yago) | + | Voir diapo du cours : Calculer la similarité entre 2 utilisateurs de MovieLens ou 2 individus de Yago |
* Définir une fonction qui calcule la similarité de Jaccard entre 2 listes d'objets : jaccard(x, y) = cardinal de l'intersection / cardinal de l'union | * Définir une fonction qui calcule la similarité de Jaccard entre 2 listes d'objets : jaccard(x, y) = cardinal de l'intersection / cardinal de l'union | ||
Ligne 707: | Ligne 717: | ||
- | ===== Exercice 5 : Questions diverses ===== | + | ===== Exercice 5 : Traitement itératif par partition et par groupe d'objets ===== |
- | La methode zipWithIndex (numérotant les éléments d'une collection) existe pour un RDD mais pas pour un DataSet. | + | La methode zipWithIndex (numérotant les éléments d'une collection) existe pour un RDD mais pas pour un Dataset. |
Ecrire la fonction ''numeroration[T](d: Dataset[T])'' qui retourne un Dataset avec des éléments numérotés. Les numéros doivent être consécutifs. | Ecrire la fonction ''numeroration[T](d: Dataset[T])'' qui retourne un Dataset avec des éléments numérotés. Les numéros doivent être consécutifs. | ||
+ | Rmq: une solution consiste à utiliser mapPartitionsWithIndex pour connaitre la taille des partitions et parcourir une partition pour affecter les numéros consécutifs à chaque élément. | ||
+ | |||
+ | |||
+ | |||
+ | ===== Exercice 6 : Chemin le plus long ===== | ||
+ | Pour les données de yago utilisées précédemment, déterminer les chemins partant des sujets qui vivent (<livesIn>) en 'France'. | ||
+ | Un chemin doit être sans circuit (ou sans cycle : ne jamais repasser sur le même sujet). | ||
+ | Combien y a -t-il de chemin de longueur 2, 3 ,4 ? | ||
+ | Quelle est la longueur maximale ? | ||
+ | Montrer que votre solution est efficace. Expliquer ce que vous avez mis en oeuvre pour apporter plus d'efficacité. | ||