Fonctions Hive : Exemple de fonctions intégrées et de fonctions définies par l’utilisateur

⚡ Résumé intelligent

Les fonctions Hive se répartissent en deux groupes : les fonctions intégrées, fournies avec le moteur et couvrant les collections, les dates, les opérations mathématiques, les conditions, les chaînes de caractères et diverses autres tâches, et les fonctions définies par l’utilisateur, écrites en langage naturel. Java pour la logique que Hive ne fournit pas.

  • 📚 Six familles intégrées : Les fonctions de collection, de date, mathématiques, conditionnelles, de chaîne de caractères et diverses autres fonctions sont directement appelables dans HiveQL.
  • 🧾 Les signatures sont importantes : Chaque fonction possède une liste d'arguments fixe et un type de retour documenté ; c'est donc le type de retour qui détermine où elle peut être utilisée.
  • 🧩 Les UDF comblent les lacunes : Lorsqu'aucune fonction intégrée n'existe, une Java La classe étendant org.apache.hadoop.hive.ql.exec.UDF fournit l'opération manquante.
  • (I.e. Trois formes de fonction personnalisée : UDF renvoie une ligne par ligne, UDAF réduit plusieurs lignes à une seule et UDTF développe une ligne en plusieurs.
  • Inscription en deux étapes : ADD JAR place le code dans le classpath et CREATE TEMPORARY FUNCTION associe un nom à la classe.
  • ♻️ L'essentiel, c'est la réutilisation : Une fonction définie par l'utilisateur (UDF) testée, telle qu'un stemmer, peut être appelée depuis chaque requête au lieu d'être réécrite à chaque fois.

Fonctions Hive : Fonctions intégrées et définies par l’utilisateur

Les fonctions sont conçues dans un but précis : effectuer des opérations mathématiques, arithmétiques, logiques et relationnelles sur les opérandes que sont les noms de colonnes d'un tableau.

Fonctions intégrées

Ce sont des fonctions déjà disponibles dans Hive. Tout d’abord, nous devons vérifier les exigences de l’application, puis nous pouvons utiliser ces fonctions intégrées dans nos applications. Nous pouvons appeler ces fonctions directement dans notre application.

La syntaxe et les types sont mentionnés dans la section suivante.

Types de fonctions intégrées dans Hive :

  • Fonctions de collecte
  • Fonctions de date
  • Fonctions mathématiques
  • Fonctions conditionnelles
  • Fonctions de chaîne
  • Divers. Les fonctions

Chacune des six familles est présentée ci-dessous avec ses signatures de fonction et ses types de retour.

Fonctions de collecte

Ces fonctions sont utilisées pour les collections. Les collections désignent le groupeping de éléments, et elles renvoient un seul élément ou un tableau d'éléments selon le type de retour mentionné dans le nom de la fonction.

Type de retour Nom de la fonction Description
INT taille (Carte ) Il récupérera et fournira le nombre de composants dans le type de carte
INT taille (Tableau ) Elle récupérera et renverra le nombre d'éléments du type de tableau.
Tableau map_keys(Carte) ) Elle récupérera et renverra un tableau contenant les clés de la carte d'entrée. Ce tableau n'est pas ordonné.
Tableau map_values(Carte) ) Elle récupérera et renverra un tableau contenant les valeurs de la carte d'entrée. Ce tableau n'est pas ordonné.
Tableau trier_tableau(Tableau ) Trie le tableau d'entrée par ordre croissant de ses éléments et le renvoie.
Boolean tableau_contient(Tableau , valeur) Renvoie TRUE si le tableau contient la valeur passée comme deuxième argument

Fonctions de date

Ces outils servent à effectuer des manipulations de dates et à convertir des types de dates d'un type à un autre :

Nom de la fonction Type de retour Description
unix_timestamp() BigInt Nous allons obtenir le courant Unix Horodatage en secondes. La valeur n'est pas fixe pour toute la requête.
à_date(chaîne horodatage) données Elle récupérera et fournira la partie date d'une chaîne d'horodatage.
année (date de chaîne) INT Il récupérera et donnera l'année une partie d'une date ou une chaîne d'horodatage
trimestre (date/horodatage/chaîne) INT Il récupérera et donnera le trimestre de l'année pour une date, un horodatage ou une chaîne comprise entre 1 et 4.
mois (date de chaîne) INT Il donnera la partie mois d'une date ou d'une chaîne d'horodatage
heure (date de chaîne) INT Il récupérera et affichera l'heure de l'horodatage.
minute (date de chaîne) INT Il récupérera et affichera la minute de l'horodatage.
date_sub(chaîne date de début, entier jours) données Il récupérera et fournira le résultat de la sous-routinetracen un certain nombre de jours à compter de la date de début
date_actuelle données Elle récupérera et fournira la date actuelle au début de l'évaluation de la requête.
dernier_jour(chaîne de caractères date) string Il récupérera et affichera le dernier jour du mois auquel appartient la date.
tronc (date de chaîne, format de chaîne) string Il récupérera et fournira la date tronquée à l'unité spécifiée par le format. Les formats supportés: MOIS/LUN/MM, ANNÉE/AAAA/AA.

Fonctions mathématiques

Ces fonctions servent à effectuer des opérations mathématiques. Au lieu de créer des UDF (User Data Functions), Hive dispose de fonctions mathématiques intégrées.

Nom de la fonction Type de retour Description
rond (DOUBLE X) DOUBLE Elle récupérera et renverra la valeur BIGINT arrondie de X.
rond (DOUBLE X, INT d) DOUBLE Elle récupérera et renverra X arrondi à d décimales.
rond(DOUBLE X) DOUBLE Elle récupérera et renverra la valeur BIGINT arrondie de X en utilisant le mode d'arrondi HALF_EVEN, également connu sous le nom d'arrondi bancaire.
étage(DOUBLE X) GRAND Elle récupérera et renverra la valeur BIGINT maximale inférieure ou égale à la valeur X.
plafond(DOUBLE a), plafond(DOUBLE a) GRAND Elle récupérera et renverra la valeur BIGINT minimale égale ou supérieure à la valeur a
rand(), rand(graine INT) DOUBLE Elle générera et renverra un nombre aléatoire uniformément distribué entre 0 et 1. Fournir une graine permet de répéter la séquence.

Fonctions conditionnelles

Ces fonctions sont utilisées pour les vérifications de valeurs conditionnelles.

Nom de la fonction Type de retour Description
if (Boolean testCondition, T valueTrue, T valueFalseOrNull) T Elle renverra la valeur True lorsque testCondition est vrai, et la valeur FalseOrNull sinon.
isnull(X) Boolean Elle renverra vrai si X est NULL et faux sinon.
isnotnull(X) Boolean Elle renverra vrai si X n'est pas NULL et faux sinon.
nvl(T valeur, T valeur_par_défaut) T Elle renverra default_value si la valeur est NULL, et value sinon.

Fonctions de chaîne

Les manipulations et opérations sur les chaînes de caractères sont gérées par les fonctions suivantes.

Nom de la fonction Type de retour Description
inverser(chaîne X) string Cela donnera la chaîne inversée de X
rpad (string str, longueur int, pad de chaîne) string Il récupérera et donnera str, complété à droite par un pad, jusqu'à une longueur totale de longueur
rtrim(chaîne X) string Elle récupérera et renverra la chaîne résultant de la suppression des espaces à la fin (côté droit) de X.
Par exemple, rtrim(' résultats ') donne ' résultats '
espace(INT n) string Il récupérera et renverra une chaîne de n espaces.
split(STRING str, STRING pat) tableau Divise str autour de pat (pat est une expression régulière).
str_to_map(texte[, délimiteur1, délimiteur2]) carte Il divisera le texte en paires clé-valeur à l'aide de deux délimiteurs. Le délimiteur 1 sépare les paires et le délimiteur 2 sépare chaque paire.

Divers. Les fonctions

Plusieurs fonctions intégrées n'appartiennent à aucune des familles ci-dessus. Elles couvrent le hachage, les informations de session et l'appel de fonctions arbitraires. Java méthodes.

Nom de la fonction Type de retour Description
hash(a1[, a2…]) INT Renvoie une valeur de hachage des arguments
utilisateur_actuel() string Renvoie le nom d'utilisateur actuel à partir du gestionnaire d'authentification configuré.
base_de_données_actuelle() string Renvoie le nom de la base de données actuelle
md5(chaîne/binaire) string Renvoie la somme de contrôle MD5 128 bits sous forme de chaîne de 32 chiffres hexadécimaux, ou NULL pour un argument NULL.
sha1(chaîne/binaire) string Renvoie le condensé SHA-1 de l'argument sous forme de chaîne hexadécimale
crc32(chaîne/binaire) BigInt Renvoie la valeur de contrôle de redondance cyclique d'un argument de type chaîne ou binaire
version() string Renvoie la version de Hive sous la forme d'un numéro de build suivi d'un hachage de build.
réfléchir(classe, méthode[, arg1…]) varie appelle un Java méthode en faisant correspondre la signature de l'argument, en utilisant la réflexion. java_method() est un synonyme

UDF (fonctions définies par l'utilisateur)

Dans Hive, les utilisateurs peuvent définir leurs propres fonctions pour répondre à certains besoins clients. Ces fonctions sont appelées UDF (User-Defined Functions) dans Hive. Les fonctions définies par l'utilisateur sont écrites en Java pour des modules spécifiques.

Certaines UDF sont spécifiquement conçues pour la réutilisation du code dans les frameworks d'application. Le développeur écrit ces fonctions dans Java et intègre ces UDF à Hive.

Lors de l'exécution d'une requête, le développeur peut utiliser directement le code, et les fonctions définies par l'utilisateur (UDF) renverront les résultats conformément aux tâches définies. Cette approche offre des performances élevées en termes de codage et d'exécution.

Par exemple, pour la racinisation des chaînes de caractères, Hive ne propose aucune fonction prédéfinie. Pour cela, nous pouvons écrire une UDF de racinisation dans Java. Partout où nous avons besoin des fonctionnalités de la tige, nous pouvons appeler directement cette UDF de tige dans Hive.

Ici, la fonctionnalité de racinisation consiste à extraire les mots de leur racine. Un algorithme de racinisation réduit les mots « wishing », « wished » et « wishes » à la racine « wish ». Pour réaliser ce type de fonctionnalité, nous pouvons écrire une UDF. Java et l'intégrer à Ruche.

Selon le cas d'utilisation, la fonction définie par l'utilisateur (UDF) peut être écrite pour accepter et produire un nombre différent de valeurs d'entrée et de sortie.

Le type général de fonction définie par l'utilisateur (UDF) accepte une seule valeur d'entrée et produit une seule valeur de sortie. Si l'UDF est utilisée dans une requête, elle sera appelée une fois pour chaque ligne du jeu de données de résultats.

Inversement, une fonction peut accepter un groupe de valeurs en entrée et renvoyer une seule valeur en sortie. C’est cette différence qui distingue les trois types de fonctions personnalisées décrits ci-après.

UDF vs UDAF vs UDTF dans Hive

Dans Hive, les fonctions personnalisées sont regroupées selon le nombre de lignes en entrée et en sortie. Choisir un type incorrect est la raison la plus fréquente pour laquelle une fonction personnalisée refuse de compiler ou renvoie une seule ligne au lieu d'un tableau.

Type Lignes entrantes → lignes sortantes Classe à étendre Exemples intégrés
UDF Une rangée → une rangée org.apache.hadoop.hive.ql.exec.UDF longueur(), arrondi(), inverser()
UDAF Plusieurs rangées → une seule rangée org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver compter(), min(), max()
UDTF Une rangée → plusieurs rangées org.apache.hadoop.hive.ql.udf.generic.GenericUDTF explode(), json_tuple(), parse_url_tuple()

Deux règles pratiques découlent du tableau :

  • Une UDAF est presque toujours associée à une clause GROUP BY, car elle réduit chaque groupe à une seule ligne.
  • Une UDTF ne peut pas être sélectionnée en même temps que d'autres colonnes dans la même liste SELECT ; elle est donc normalement utilisée avec une VUE LATÉRALE.

Il existe également une seconde classe de base plus performante pour le travail au niveau des lignes, GenericUDF, qui accepte des types complexes tels que des tableaux, des maps et des structures, ainsi qu'un nombre variable d'arguments.

Comment écrire et enregistrer une UDF dans Hive

L'exemple de tige décrit ci-dessus peut être construit comme une véritable fonction en quatre étapes. Rien de plus qu'un Java Un compilateur et une session Hive en cours d'exécution sont nécessaires.

Étape 1) Rediger un Java Classe étendant UDF et implémentant une méthode publique evaluate(). Hive appelle evaluate() une fois par ligne ; la méthode doit donc gérer une entrée NULL.

package com.guru99.hive.udf;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public final class Stem extends UDF {

    public Text evaluate(final Text input) {
        if (input == null) {
            return null;
        }
        String word = input.toString().toLowerCase();
        if (word.endsWith("ing")) {
            word = word.substring(0, word.length() - 3);
        } else if (word.endsWith("ed") || word.endsWith("es")) {
            word = word.substring(0, word.length() - 2);
        }
        return new Text(word);
    }
}

Étape 2) Compilez la classe et empaquetez-la dans un fichier JAR, par exemple hive-udf-1.0.jar, avec toutes les classes dont elle dépend.

Étape 3) Placez le fichier JAR dans le classpath de Hive et associez un nom de fonction à la classe. Une fonction temporaire n'est valide que pour la session en cours.

ADD JAR /home/hduser/hive-udf-1.0.jar;

CREATE TEMPORARY FUNCTION stem AS 'com.guru99.hive.udf.Stem';

Étape 4) Appelez la nouvelle fonction exactement comme une fonction intégrée. Appliquée aux mots « wishing », « wished » et « wishes », cette classe renvoie « wish » pour les trois.

SELECT word, stem(word) FROM words;

Pour que la fonction reste accessible à chaque session et à chaque utilisateur, il est préférable de l'enregistrer de manière permanente dans une base de données. Le fichier JAR doit se trouver sur un chemin accessible en lecture à l'ensemble du cluster, généralement HDFS.

CREATE FUNCTION default.stem AS 'com.guru99.hive.udf.Stem'
USING JAR '/user/hive/udfs/hive-udf-1.0.jar';

Une même classe peut déclarer plusieurs méthodes `evaluate()`. Hive compare l'appel aux signatures des arguments, ce qui permet à une fonction d'accepter à la fois une chaîne de caractères et un entier.

FAQ

La commande SHOW FUNCTIONS liste tous les noms enregistrés, y compris les noms personnalisés. La commande DESCRIBE FUNCTION nom affiche une signature sur une seule ligne, et la commande DESCRIBE FUNCTION EXTENDED nom ajoute des exemples d'utilisation lorsque la classe d'implémentation les fournit.

Il s'agit presque toujours d'un problème de nom ou de portée : la chaîne de caractères après AS doit correspondre au nom de classe complet, et ADD JAR ne s'applique qu'à la session qui l'a exécuté. La reconnexion supprime à la fois le fichier JAR et toute fonction temporaire.

Utilisez GenericUDF lorsque la fonction accepte des types complexes tels que des tableaux, des dictionnaires ou des structures, un nombre variable d'arguments, ou lorsqu'elle doit valider elle-même les types de ses arguments. La classe UDF simple résout les types par réflexion et ne gère que les types primitifs accessibles en écriture.

Une véritable UDF doit s'exécuter sur la JVM. Pour les autres langages, Ruche offre la clause TRANSFORM, qui traite chaque ligne via un script externe tel que Python via les entrées et sorties standard. C'est plus lent, mais cela évite… Java entièrement.

Oui. La fonction `evaluate()` s'exécute une fois par ligne, ce qui multiplie le coût des opérations complexes par le nombre de lignes, et l'allocation d'objets à l'intérieur de la méthode sollicite davantage le ramasse-miettes. Privilégiez une fonction intégrée lorsqu'elle existe et évitez ainsi les opérations d'entrée/sortie dans `evaluate()`.

Non. Les noms de fonctions ne sont pas sensibles à la casse ; ainsi, ROUND(), Round() et round() désignent la même fonction. Java Le nom de classe dans la clause AS est une autre question et doit correspondre exactement à la classe compilée, y compris son package.

Les assistants d'apprentissage automatique associent une description en langage clair aux signatures candidates et signalent les incompatibilités entre le type de retour et la colonne cible. Vérifiez la suggestion par rapport à la signature documentée, car les noms générés peuvent parfois appartenir à un autre dialecte SQL.

À partir d'un commentaire décrivant l'opération, elle génère une structure fonctionnelle (déclaration de classe, importations et méthode `evaluate()`). La gestion des valeurs nulles, les types modifiables et l'étape d'empaquetage restent à vérifier, et la fonction doit être testée sur des lignes réelles.

Résumez cet article avec :