Apache Pig UDF: Časť 1 - Eválne, agregačné a filtračné funkcie



Tento príspevok popisuje Apache Pig UDF - eválne, agregačné a filtračné funkcie. Zoznámte sa s funkciami Eval, Aggregate & Filter Functions.

Apache Pig poskytuje rozsiahlu podporu pre užívateľom definované funkcie (UDF) ako spôsob špecifikácie vlastného spracovania. Prasa UDF sa v súčasnosti dá spustiť v troch jazykoch: Java, Python, JavaScript a Ruby. Najrozsiahlejšia podpora je poskytovaná pre funkcie Java.





Java UDF je možné vyvolať viacerými spôsobmi. Najjednoduchší UDF môže iba rozšíriť EvalFunc, ktorý vyžaduje implementáciu iba funkcie exec. Toto musí implementovať každý Eval UDF. Ak je funkcia navyše algebraická, môže implementovať algebraické rozhranie, aby výrazne zlepšila výkonnosť dotazu.

porovnanie bábkohernej soli s bábkou

Dôležitosť UDF u ošípaných:

Prasa umožňuje používateľom kombinovať existujúcich operátorov s vlastným alebo cudzím kódom prostredníctvom UDF. Výhodou prasaťa je jeho schopnosť umožniť používateľom kombinovať jeho operátorov s ich vlastným alebo cudzím kódom prostredníctvom UDF. Až do verzie 0.7 musia byť všetky UDF napísané v jazyku Java a sú implementované ako triedy Java. Toto uľahčuje pridávanie nových UDF do Pig napísaním triedy Java a informovaním Pig o súbore JAR.



Samotné prasa je dodávané s niektorými UDF. Pred verziou 0.8 to bola veľmi obmedzená sada, ktorá mala iba štandardné agregačné funkcie SQL a niekoľko ďalších. V 0.8 bolo pridané veľké množstvo štandardných UDF na spracovanie strún, matematiky a komplexného typu.

Čo je to prasiatko?

Piggybank je zbierka používateľsky prispievaných UDF, ktorá je vydaná spolu s Pig. UDF Piggybank nie sú obsiahnuté v Pig JAR, takže ich musíte vo svojom skripte zaregistrovať manuálne. Môžete tiež napísať svoje vlastné UDF alebo použiť tie, ktoré napísali iní používatelia.

Eválne funkcie

Trieda UDF rozširuje triedu EvalFunc, ktorá je základom pre všetky funkcie Eval. Všetky vyhodnocovacie funkcie rozširujú triedu Java „org.apache.pig.EvalFunc. „Je parametrizovaný návratovým typom UDF, čo je v tomto prípade Java String. Základná metóda v tejto triede je „exec.“ Prvý riadok kódu naznačuje, že funkcia je súčasťou balíka myudfs.



Trvá jeden záznam a vráti jeden výsledok, ktorý sa vyvolá pre každý záznam, ktorý prejde potrubím vykonania. Trvá to n-ticu, ktorá obsahuje všetky polia, ktoré skript odovzdá vášmu UDF ako vstup. Potom vráti typ, podľa ktorého ste parametrizovali EvalFunc.

Táto funkcia je vyvolaná pri každej vstupnej n-tici. Vstupom do funkcie je n-tica so vstupnými parametrami v poradí, v akom sú odovzdané funkcii v skripte Pig. V príklade zobrazenom nižšie berie funkcia ako vstup reťazec. Nasledujúca funkcia prevádza reťazec z malých na veľké. Teraz, keď je funkcia implementovaná, je potrebné ju zostaviť a zahrnúť do súboru JAR.

balíček myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple verejná trieda UPPER rozširuje EvalFunc {public String exec (vstup Tuple) hodí 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)}}}

Agregované funkcie:

Agregované funkcie sú ďalším bežným typom eválnej funkcie. Agregované funkcie sa zvyčajne používajú na zoskupené údaje. Funkcia Aggregate vezme mešec a vráti skalárnu hodnotu. Zaujímavou a cennou vlastnosťou mnohých funkcií agregácie je, že sa dajú vypočítať inkrementálne distribuovaným spôsobom. Vo svete Hadoop to znamená, že čiastočné výpočty je možné vykonať pomocou aplikácie Map a Combiner a konečný výsledok je možné vypočítať pomocou redukcie.

Je veľmi dôležité zabezpečiť, aby agregačné funkcie, ktoré sú algebraické, boli implementované ako také. Medzi príklady tohto typu patria zabudované funkcie COUNT, MIN, MAX a PRIEMER.

COUNT je príklad algebraickej funkcie, keď môžeme spočítať počet prvkov v podmnožine údajov a potom ich spočítať, aby sme vytvorili konečný výstup. Pozrime sa na implementáciu funkcie COUNT:

public class COUNT extends EvalFunc implements Algebraic {public Long exec (Tuple input) throws 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 ()} static public class Initial extends EvalFunc {public Tuple exec (Tuple input) throws IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} statická verejná trieda Intermed rozširuje EvalFunc {public Tuple exec (vstup Tuple) hodí IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} statická verejná trieda Final rozširuje EvalFunc {public Tuple exec (vstup Tuple) hodí IOException {return sum (input)}} staticky chránený Long count (Tuple input) hodí ExecException {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () else if (values instanceof Map) vráti nové Long ((((Map) hodnoty)). size ())} staticky chránený Long sum (Tuple i nput) hodí 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)} návratná suma}}

COUNT implementuje algebraické rozhranie, ktoré vyzerá takto:

verejné rozhranie Algebraické {public String getInitial () public String getIntermed () public String getFinal ()}

Aby bola funkcia algebraická, je potrebné implementovať algebraické rozhranie, ktoré pozostáva z definície troch tried odvodených z EvalFunc. Zmluva spočíva v tom, že vykonanie funkcie triedy Initial sa volá raz a odovzdá sa pôvodnej n-tici. Jeho výstupom je n-tica, ktorá obsahuje čiastočné výsledky. Funkciu exec triedy Intermed možno nazvať nula alebo viackrát a berie ako svoj vstup n-ticu, ktorá obsahuje čiastočné výsledky vytvorené triedou Initial alebo predchádzajúcimi vyvolaniami triedy Intermed a vytvára n-ticu s ďalším čiastkovým výsledkom. Nakoniec sa zavolá funkcia exec triedy Final, ktorá dáva konečný výsledok ako skalárny typ.

Funkcie filtra:

Funkcie filtra sú Eválne funkcie, ktoré vracajú logickú hodnotu. Môže sa použiť kdekoľvek, kde je vhodný logický výraz, vrátane operátora FILTER alebo výrazu Bincond. Apache Pig úplne nepodporuje logické hodnoty, takže funkcie filtra sa nemôžu zobrazovať vo výrokoch ako napríklad „Foreach“, kde sú výsledky odosielané inému operátorovi. Funkcie filtra však možno použiť vo výpisoch filtra.

Nasledujúci príklad implementuje funkciu IsEmpty:

náhodná trieda v príklade java
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 / ** * Zistite, či je taška alebo mapa prázdna. * / public class IsEmpty extends 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 (values ​​instanceof Map) return ((Map) values) .size () == 0 else {int errCode = 2102 String msg = 'Nemôžem otestovať' + DataType.findTypeName (values) + 'na prázdnotu.' hodiť novú ExecException (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}