Apache Pig UDF: Parte 1 - Funzioni di valutazione, aggregazione e filtro



Questo post descrive le funzioni UDF di Apache Pig: valutazione, aggregazione e filtro. Dai un'occhiata alle funzioni di valutazione, aggregazione e filtro.

Apache Pig fornisce un ampio supporto per le funzioni definite dall'utente (UDF) come un modo per specificare l'elaborazione personalizzata. Le UDF di Pig possono attualmente essere eseguite in tre lingue: Java, Python, JavaScript e Ruby. Il supporto più ampio è fornito per le funzioni Java.





Le UDF Java possono essere richiamate in diversi modi. L'UDF più semplice può semplicemente estendere EvalFunc, che richiede solo l'implementazione della funzione exec. Ogni UDF di valutazione deve implementarlo. Inoltre, se una funzione è algebrica, può implementare l'interfaccia algebrica per migliorare significativamente le prestazioni delle query.

Importanza delle UDF in Pig:

Pig consente agli utenti di combinare gli operatori esistenti con il proprio codice o quello di altri tramite UDF. Il vantaggio di Pig è la sua capacità di consentire agli utenti di combinare i propri operatori con il proprio codice o quello di altri tramite UDF. Fino alla versione 0.7, tutte le UDF devono essere scritte in Java e vengono implementate come classi Java. Ciò semplifica l'aggiunta di nuove UDF a Pig scrivendo una classe Java e informando Pig del file JAR.



Il maiale stesso viene fornito con alcune UDF. Prima della versione 0.8, era un insieme molto limitato con solo le funzioni di aggregazione SQL standard e poche altre. In 0.8, è stato aggiunto un gran numero di UDF di tipo complesso, matematiche e di elaborazione di stringhe standard.

imposta il classpath java in linux

Cos'è un salvadanaio?

Piggybank è una raccolta di UDF fornite dagli utenti che viene rilasciata insieme a Pig. Le UDF Piggybank non sono incluse nel JAR Pig, quindi è necessario registrarle manualmente nel proprio script. Puoi anche scrivere le tue UDF o usare quelle scritte da altri utenti.

Funzioni di valutazione

La classe UDF estende la classe EvalFunc che è la base per tutte le funzioni Eval. Tutte le funzioni di valutazione estendono la classe Java 'org.apache.pig.EvalFunc. 'È parametrizzato con il tipo restituito dell'UDF che in questo caso è una stringa Java. Il metodo principale in questa classe è 'exec'. La prima riga del codice indica che la funzione fa parte del pacchetto myudfs.



Richiede un record e restituisce un risultato, che verrà richiamato per ogni record che passa attraverso la pipeline di esecuzione. Richiede una tupla, che contiene tutti i campi che lo script passa all'UDF come input. Restituisce quindi il tipo in base al quale è stato parametrizzato EvalFunc.

Questa funzione viene invocata su ogni tupla di input. L'input nella funzione è una tupla con parametri di input nell'ordine in cui sono passati alla funzione nello script Pig. Nell'esempio mostrato di seguito, la funzione accetta la stringa come input. La seguente funzione converte la stringa da minuscolo a maiuscolo. Ora che la funzione è implementata, deve essere compilata e inclusa in un JAR.

pacchetto myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple public class UPPER extends EvalFunc {public String exec (Tuple input) throws 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)}}}

Funzioni aggregate:

Le funzioni aggregate sono un altro tipo comune di funzione Eval. Le funzioni aggregate vengono generalmente applicate ai dati raggruppati. La funzione Aggregate prende una borsa e restituisce un valore scalare. Una caratteristica interessante e preziosa di molte funzioni di aggregazione è che possono essere calcolate in modo incrementale in modo distribuito. Nel mondo Hadoop, ciò significa che i calcoli parziali possono essere eseguiti da Map e Combiner e il risultato finale può essere calcolato dal Reducer.

È molto importante assicurarsi che le funzioni aggregate algebriche siano implementate come tali. Esempi di questo tipo includono COUNT, MIN, MAX e MEDIA incorporati.

CONTARE è un esempio di una funzione algebrica in cui possiamo contare il numero di elementi in un sottoinsieme di dati e quindi sommare i conteggi per produrre un output finale. Diamo un'occhiata all'implementazione della funzione COUNT:

la classe pubblica COUNT estende EvalFunc implementa Algebraic {public Long exec (Tuple input) genera 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 ()} statica public class Initial estende EvalFunc {public Tuple exec (Tuple input) genera IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} classe pubblica statica Intermed estende EvalFunc {public Tuple exec (Tuple input) genera IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} classe pubblica statica Final estende EvalFunc {public Tuple exec (Tuple input) throws IOException {return sum (input)}} static protected Long count (Tuple input) genera ExecException {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () else if (values instanceof Map) restituisce nuovi Long (((Map) values) .size ())} static protected Long sum (Tuple i nput) genera 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 implementa l'interfaccia algebrica che assomiglia a questa:

interfaccia pubblica Algebrica {public String getInitial () public String getIntermed () public String getFinal ()}

Affinché una funzione sia algebrica, è necessario implementare l'interfaccia algebrica che consiste nella definizione di tre classi derivate da EvalFunc. Il contratto prevede che la funzione exec della classe Initial venga chiamata una volta e passata alla tupla di input originale. Il suo output è una tupla che contiene risultati parziali. La funzione exec della classe Intermed può essere chiamata zero o più volte e prende come input una tupla che contiene risultati parziali prodotti dalla classe Initial o da precedenti invocazioni della classe Intermed e produce una tupla con un altro risultato parziale. Infine, viene chiamata la funzione exec della classe Final e fornisce il risultato finale come tipo scalare.

Funzioni di filtro:

Le funzioni di filtro sono funzioni Eval che restituiscono un valore booleano. Può essere utilizzato ovunque sia appropriata un'espressione booleana, incluso l'operatore FILTER o l'espressione Bincond. Apache Pig non supporta completamente Boolean, quindi le funzioni Filter non possono apparire in istruzioni come 'Foreach', dove i risultati vengono inviati a un altro operatore. Tuttavia, le funzioni Filter possono essere utilizzate nelle istruzioni filter.

programma della serie fibonacci in java

L'esempio seguente implementa la funzione 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 / ** * Determina se una borsa o una mappa è vuota. * / public class IsEmpty estende FilterFunc {@Override public Boolean exec (Tuple input) genera 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 = 'Cannot test a' + DataType.findTypeName (values) + 'for emptiness.' lancia una nuova ExecException (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}