Apache Pig UDF: Partie 1 - Fonctions d'évaluation, d'agrégation et de filtrage



Cet article décrit Apache Pig UDF - Fonctions d'évaluation, d'agrégation et de filtrage. Jetez un œil aux fonctions d'évaluation, d'agrégation et de filtrage.

Apache Pig fournit une prise en charge étendue des fonctions définies par l'utilisateur (UDF) comme moyen de spécifier un traitement personnalisé. Les UDF Pig peuvent actuellement être exécutés en trois langues: Java, Python, JavaScript et Ruby. Le support le plus complet est fourni pour les fonctions Java.





Les UDF Java peuvent être appelées de plusieurs manières. L'UDF le plus simple peut simplement étendre EvalFunc, ce qui ne nécessite que la fonction exec à implémenter. Chaque Eval UDF doit l'implémenter. De plus, si une fonction est algébrique, elle peut implémenter une interface algébrique pour améliorer considérablement les performances des requêtes.

Importance des UDF chez le porc:

Pig permet aux utilisateurs de combiner des opérateurs existants avec leur propre code ou celui des autres via des UDF. L’avantage de Pig est sa capacité à permettre aux utilisateurs de combiner ses opérateurs avec leur propre code ou celui d’autres via des UDF. Jusqu'à la version 0.7, tous les UDF doivent être écrits en Java et sont implémentés en tant que classes Java. Cela facilite l'ajout de nouveaux UDF à Pig en écrivant une classe Java et en informant Pig du fichier JAR.



Pig lui-même est livré avec des UDF. Avant la version 0.8, il s'agissait d'un ensemble très limité avec uniquement les fonctions d'agrégation SQL standard et quelques autres. Dans la version 0.8, un grand nombre d'UDF standard de traitement de chaînes, de mathématiques et de type complexe ont été ajoutés.

Qu'est-ce qu'une tirelire?

Piggybank est une collection d'UDF contribués par les utilisateurs qui est publié avec Pig. Les UDF Piggybank ne sont pas inclus dans le JAR Pig, vous devez donc les enregistrer manuellement dans votre script. Vous pouvez également écrire vos propres UDF ou utiliser ceux écrits par d'autres utilisateurs.

Fonctions d'évaluation

La classe UDF étend la classe EvalFunc qui est la base de toutes les fonctions Eval. Toutes les fonctions d'évaluation étendent la classe Java «org.apache.pig.EvalFunc. «Il est paramétré avec le type de retour de l’UDF qui est une chaîne Java dans ce cas. La méthode principale de cette classe est «exec». La première ligne du code indique que la fonction fait partie du package myudfs.



algorithmes d'apprentissage automatique en r

Il prend un enregistrement et renvoie un résultat, qui sera appelé pour chaque enregistrement qui passe par le pipeline d'exécution. Il prend un tuple, qui contient tous les champs que le script transmet à votre UDF en tant qu'entrée. Il renvoie ensuite le type par lequel vous avez paramétré EvalFunc.

Cette fonction est appelée sur chaque tuple d'entrée. L'entrée dans la fonction est un tuple avec des paramètres d'entrée dans l'ordre dans lequel ils sont passés à la fonction dans le script Pig. Dans l'exemple ci-dessous, la fonction prend une chaîne comme entrée. La fonction suivante convertit la chaîne de minuscules en majuscules. Maintenant que la fonction est implémentée, elle doit être compilée et incluse dans un JAR.

package myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple classe publique UPPER étend EvalFunc {public String exec (Tuple input) jette IOException {if (input == null || input.size () == 0) return null try {String str = (String) input.get (0) return str.toUpperCase ()} catch (Exception e) {throw new IOException ('Caught exception processing input row', e)}}}

Fonctions d'agrégation:

Les fonctions d'agrégation sont un autre type courant de fonction Eval. Les fonctions d'agrégation sont généralement appliquées aux données groupées. La fonction Aggregate prend un sac et renvoie une valeur scalaire. Une caractéristique intéressante et précieuse de nombreuses fonctions d'agrégation est qu'elles peuvent être calculées de manière incrémentielle de manière distribuée. Dans le monde Hadoop, cela signifie que les calculs partiels peuvent être effectués par le Map et le Combiner et le résultat final peut être calculé par le Reducer.

Il est très important de s'assurer que les fonctions d'agrégation algébriques sont implémentées comme telles. Les exemples de ce type incluent les COUNT, MIN, MAX et AVERAGE intégrés.

COMPTER est un exemple de fonction algébrique où nous pouvons compter le nombre d'éléments dans un sous-ensemble de données, puis additionner les décomptes pour produire une sortie finale. Examinons la mise en œuvre de la fonction COUNT:

classe publique COUNT étend EvalFunc implements Algebraic {public Long exec (Tuple input) jette IOException {return count (input)} public String getInitial () {return Initial.class.getName ()} public String getIntermed () {return Intermed.class. getName ()} public String getFinal () {return Final.class.getName ()} classe publique statique Initial étend EvalFunc {public Tuple exec (Tuple input) throws IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} classe publique statique Intermed étend EvalFunc {exécute Tuple public (entrée Tuple) jette IOException {return TupleFactory.getInstance (). newTuple (somme (entrée))}} classe publique statique Final étend EvalFunc {exécute Tuple public (entrée Tuple) IOException {return sum (input)}} static protected Long count (Tuple input) jette ExecException {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () else if (values instanceof Map) return new Long (((Map) values) .size ())} static protected Long sum (Tuple i nput) lance ExecException, NumberFormatException {DataBag values ​​= (DataBag) input.get (0) long sum = 0 for (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) sum + = (Long) t.get (0)} return sum}}

COUNT implémente une interface algébrique qui ressemble à ceci:

interface publique Algébrique {chaîne publique getInitial () chaîne publique getIntermed () chaîne publique getFinal ()}

Pour qu'une fonction soit algébrique, elle doit implémenter une interface algébrique qui consiste en la définition de trois classes dérivées d'EvalFunc. Le contrat est que la fonction d'exécution de la classe Initial est appelée une fois et est passée au tuple d'entrée d'origine. Sa sortie est un tuple qui contient des résultats partiels. La fonction exec de la classe Intermed peut être appelée zéro ou plusieurs fois et prend comme entrée un tuple qui contient des résultats partiels produits par la classe Initial ou par des appels antérieurs de la classe Intermed et produit un tuple avec un autre résultat partiel. Enfin, la fonction exec de la classe Final est appelée et donne le résultat final sous forme de type scalaire.

goto, fonction c ++

Fonctions de filtrage:

Les fonctions de filtre sont des fonctions Eval qui retournent une valeur booléenne. Il peut être utilisé partout où une expression booléenne est appropriée, y compris l'opérateur FILTER ou l'expression Bincond. Apache Pig ne prend pas totalement en charge les valeurs booléennes, les fonctions de filtre ne peuvent donc pas apparaître dans des instructions telles que «Foreach», où les résultats sont envoyés à un autre opérateur. Cependant, les fonctions de filtre peuvent être utilisées dans les instructions de filtre.

L'exemple ci-dessous implémente la fonction IsEmpty:

import java.io.IOException import java.util.Map import org.apache.pig.FilterFunc import org.apache.pig.PigException import org.apache.pig.backend.executionengine.ExecException import org.apache.pig.data.DataBag import org.apache.pig.data.Tuple import org.apache.pig.data.DataType / ** * Détermine si un sac ou une carte est vide. * / public class IsEmpty étend FilterFunc {@Override public Boolean exec (Tuple input) jette IOException {try {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () == 0 else if (values ​​instanceof Map) return ((Map) values) .size () == 0 else {int errCode = 2102 String msg = 'Impossible de tester un' + DataType.findTypeName (values) + 'pour la vacuité.' throw new ExecException (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}