Apache Pig UDF: Partea 1 - Funcții de evaluare, agregare și filtrare



Această postare descrie despre Apache Pig UDF - Funcții de evaluare, agregare și filtrare. Aruncați o privire la funcțiile Eval, Aggregate & Filter.

Apache Pig oferă suport extins pentru funcțiile definite de utilizator (UDF) ca modalitate de a specifica procesarea personalizată. UDF-urile Pig pot fi executate în prezent în trei limbi: Java, Python, JavaScript și Ruby. Cel mai extins suport este oferit pentru funcțiile Java.





UDF-urile Java pot fi invocate prin mai multe moduri. Cel mai simplu UDF poate extinde doar EvalFunc, care necesită doar funcția exec pentru a fi implementată. Fiecare Eval UDF trebuie să implementeze acest lucru. În plus, dacă o funcție este algebrică, poate implementa interfața algebrică pentru a îmbunătăți semnificativ performanța interogării.

Importanța UDF la porc:

Pig permite utilizatorilor să combine operatorii existenți cu codul propriu sau al altora prin UDF. Avantajul Pig este capacitatea sa de a permite utilizatorilor să-și combine operatorii cu codul propriu sau al altora prin UDF-uri. Până la versiunea 0.7, toate UDF-urile trebuie să fie scrise în Java și sunt implementate ca clase Java. Acest lucru face mai ușor să adăugați noi UDF-uri la Pig scriind o clasă Java și informând Pig despre fișierul JAR.



Porcul în sine vine cu unele UDF-uri. Înainte de versiunea 0.8, era un set foarte limitat, cu doar funcțiile standard SQL agregate și câteva altele. În 0.8, s-au adăugat un număr mare de UDF standard de procesare a șirurilor, matematică și de tip complex.

Ce este un Piggybank?

Piggybank este o colecție de UDF-uri contribuite de utilizator, care este lansată împreună cu Pig. UDF-urile Piggybank nu sunt incluse în Pig JAR, deci trebuie să le înregistrați manual în scriptul dvs. De asemenea, puteți scrie propriile UDF-uri sau le puteți utiliza pe cele scrise de alți utilizatori.

Funcții Eval

Clasa UDF extinde clasa EvalFunc care este baza pentru toate funcțiile Eval. Toate funcțiile de evaluare extind clasa Java ‘org.apache.pig.EvalFunc. ‘Este parametrizat cu tipul returnat al UDF, care este un șir Java în acest caz. Metoda de bază din această clasă este „exec.” Prima linie a codului indică faptul că funcția face parte din pachetul myudfs.



Este nevoie de o înregistrare și returnează un rezultat, care va fi invocat pentru fiecare înregistrare care trece prin conducta de execuție. Este nevoie de un tuplu, care conține toate câmpurile pe care scriptul le transmite UDF ca intrare. Apoi returnează tipul prin care ați parametrizat EvalFunc.

Această funcție este invocată la fiecare tuplu de intrare. Intrarea în funcție este un tuplu cu parametrii de intrare în ordinea în care sunt trecuți funcției în scriptul Pig. În exemplul prezentat mai jos, funcția ia șir ca intrare. Următoarea funcție convertește șirul de la minuscule la majuscule. Acum că funcția este implementată, trebuie să fie compilată și inclusă într-un JAR.

pachetul 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 ('Prins excepția procesând rândul de intrare', e)}}}

Funcții agregate:

Funcțiile agregate sunt un alt tip comun de funcții Eval. Funcțiile agregate sunt de obicei aplicate datelor grupate. Funcția Agregare ia o pungă și returnează o valoare scalară. O caracteristică interesantă și valoroasă a multor funcții Agregate este că acestea pot fi calculate incremental într-o manieră distribuită. În lumea Hadoop, aceasta înseamnă că calculele parțiale pot fi făcute de către hartă și combinator, iar rezultatul final poate fi calculat de reducător.

Este foarte important să vă asigurați că funcțiile agregate care sunt algebrice sunt implementate ca atare. Exemple de acest tip includ COUNT, MIN, MAX și MEDIE încorporate.

NUMARA este un exemplu de funcție algebrică în care putem număra numărul de elemente dintr-un subset de date și apoi putem suma sumelor pentru a produce o ieșire finală. Să analizăm implementarea funcției COUNT:

public class COUNT extinde EvalFunc implementează Algebraic {public Exec lung (intrare Tuple) aruncă 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 ()} clasă publică statică Initial extinde EvalFunc {public Tuple exec (Tuple input) throws IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} static public class Intermed extinde EvalFunc {public Tuple exec (Tuple input) throws IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} static public class Final extends EvalFunc {public Tuple exec (Tuple input) throws IOException {return sum (input)}} static protejat Count lung (Tuple input) aruncă ExecException {Object values ​​= input.get (0) if (valori instanceof DataBag) return ((DataBag) values) .size () else if (valori instanceof Map) returnează noi valori lungi (((Map)) .size ())} protejate static sum lung (Tuple i nput) aruncă ExecException, NumberFormatException {valori DataBag = (DataBag) input.get (0) suma lungă = 0 pentru (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) sum + = (Long) t.get (0)} return sum}}

COUNT implementează interfața algebrică care arată astfel:

interfață publică Algebră {public String getInitial () public String getIntermed () public String getFinal ()}

Pentru ca o funcție să fie algebrică, trebuie să implementeze o interfață algebrică care constă în definirea a trei clase derivate din EvalFunc. Contractul constă în faptul că funcția de executare a clasei Initial este apelată o singură dată și este transmisă tuplului de intrare original. Ieșirea sa este un tuplu care conține rezultate parțiale. Funcția exec a clasei Intermed poate fi numită zero sau de mai multe ori și ia ca intrare un tuplu care conține rezultate parțiale produse de clasa inițială sau prin invocații anterioare ale clasei Intermed și produce un tuplu cu alt rezultat parțial. În cele din urmă, funcția exec a clasei Finale este apelată și dă rezultatul final ca tip scalar.

Funcții de filtrare:

Funcțiile de filtrare sunt funcții Eval care returnează o valoare booleană. Poate fi folosit oriunde este adecvată o expresie booleană, inclusiv operatorul FILTER sau expresia Bincond. Apache Pig nu acceptă total booleanul, deci funcțiile de filtrare nu pot apărea în instrucțiuni precum „Foreach”, unde rezultatele sunt transmise unui alt operator. Cu toate acestea, funcțiile de filtrare pot fi utilizate în instrucțiunile de filtrare.

tutorial mysql pentru începători cu exemple

Exemplul de mai jos implementează funcția 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ți dacă o pungă sau o hartă este goală. * / public class IsEmpty extinde FilterFunc {@Override public Boolean exec (Tuple input) throws IOException {try {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () == 0 else if (valori instanceof Map) return ((Map) values) .size () == 0 else {int errCode = 2102 String msg = 'Nu se poate testa un' + DataType.findTypeName (valori) + 'pentru gol.' arunca ExecException nou (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}