La création d’User Defined Functions (UDFs) permet aux utilisateurs d’étendre les possibilités de HiveQL.
HiveQL (Hive Query Language) est un langage proche du SQL permettant d’effectuer des jobs Map / Reduce sur des données stockées dans un cluster Hadoop.
Il existe trois types de fonctions dans Hive :
- User Defined Function (UDF) : Travail ligne par ligne, une ligne en entré = une ligne en sorte (Exemple : LOWER, SUBSTR, …)
- User Defined Aggregate Functions (UDAF) : Travail sur plusieurs lignes en entrée et renvoie une ligne en sortie. (Exemples : COUNT, MAX, …)
- User Defined Table Generating Functions (UDTF) : Travail à partir d’une ligne et renvoie plusieurs lignes
Vous pouvez retrouver la liste de toutes les fonctions chargées dans la session grâce à la requête suivante:
hive> SHOW FUNCTIONS;
Vous pouvez retrouver une description / aide sur l’utilisation des fonctions à l’aide des requêtes suivantes:
hive> DESCRIBE FUNCTION UPPER;
hive> DESCRIBE FUNCTION EXTENDED LOWER;
Création d’une UDF
Pourquoi ?
Problématique rencontrée pour un POC : des logs aux formats JSON sur les films et publicités visualisés dans les salles de cinéma doivent être analysés.
Voici à quoi ressemblent les logs au format XML :
Les logs sont uploadés dans un Blob Storage Azure, ils sont ensuite copiés dans le cluster Hadoop et accessibles depuis une table Hive Externe.
Hive possède déjà des fonctions permettant de naviguer dans un JSON, ainsi pour aller chercher le nom de la publicité j’utilise la fonction get_json_object :
SELECT get_json_object(json_lecture, '$.LogEventList.ClipLogList.Title') FROM MaTable
--- La fonction Explode
La fonction Explode attend en entrée un tableau et renvoie les éléments du tableau sur plusieurs lignes.
Exemple : Considérons une table nommée MaTable qui a une seule colonne ‘MaColonne’ de type Array :
SELECT explode(MaColonne) AS MaNouvelleColonne FROM MaTable;
--- Lateral View
Lateral View est utilisé conjointement avec une UDF comme Explode() : l’UDF est d’abord appliquée à chacune des lignes, le résultat est stocké dans une table virtuelle et une jointure est ensuite faite entre les deux tables.
SELECT ID, ColonneVirtuel FROM MaTable LATERAL VIEW explode(MaColonne) MaTableVirtuel AS ColonneVirtuel;
--- Multiple Lateral View
Lateral View peut aussi être utilisé sur plusieurs colonnes de type Array :
SELECT ColonneVirtuel1, ColonneVirtuel2 FROM MaTable LATERAL VIEW explode(MaColonne1) MaTableVirtuel1 AS ColonneVirtuel1 LATERAL VIEW explode(MaColonne2) MaTableVirtuel1 AS ColonneVirtuel2;
--- Format attendu !!!
Développement de l’UDF
Les User Defined Function sont développés en Java, la documentation Apache Hive Plugins et le livre Programming Hive Data Warehouse and Query Language for Hadoop m’ont bien aidé pour démarrer.
Depuis Eclipse j’ai créé un nouveau projet, une nouvelle classe ExplodeArray et j’ai rajouté les librairies externes Hadoop-Core, Hadoop-Tools et Hive-exec. Je me suis aussi inspiré d’une UDF générique Explode2.
Installation
Une fois compilé, j’ai copié le .JAR sur le cluster Hadoop et l’ai inscrit dans Hive :
hive> ADD JAR /#PATH#/ExplodeArray.jar;
hive> CREATE TEMPORARY FUNCTION ExplodeArray AS 'com.example.hive.udf.ExplodeArray';
Résultat
Il ne reste plus qu’à tester mon UDF en lui passant 4 colonnes de types Array :
SELECT "A" as A, "B" as B, MyMovieTitle, MyPlayoutComplete, MyDate_Start, MyDate_End FROM lecture LATERAL VIEW ExplodeArray(Array(1,2,3), Array(4,5,6), Array(7,8,9), Array(10,11,12)) TitleInfoTable As MyMovieTitle,MyPlayoutComplete, MyDate_Start, MyDate_End;
Vous pouvez la télécharger et l’essayer :
Merci à Jérôme Christ @christjerome pour son aide en Java 😉
Merci pour ce tutoriel très claire et bien rédigé.