Apache Pig UDF: Part 1 - Eval, Aggregate & Filter Functions

Tento příspěvek popisuje Apache Pig UDF - Eval, Aggregate & Filter Functions. Podívejte se na funkce Eval, Aggregate & Filter Functions.

Apache Pig poskytuje rozsáhlou podporu pro funkce definované uživatelem (UDF) jako způsob, jak určit vlastní zpracování. Prasečí UDF lze aktuálně provádět ve třech jazycích: Java, Python, JavaScript a Ruby. Nejrozsáhlejší podpora je poskytována pro funkce Java.





Java UDF lze vyvolat několika způsoby. Nejjednodušší UDF může pouze rozšířit EvalFunc, který vyžaduje implementaci pouze funkce exec. Toto musí implementovat každý Eval UDF. Pokud je funkce algebraická, může implementovat algebraické rozhraní a výrazně tak zlepšit výkon dotazu.

jak používat jmenný prostor v C ++

Důležitost UDF u prasete:

Pig umožňuje uživatelům kombinovat existující operátory s vlastním nebo cizím kódem prostřednictvím UDF. Výhodou prasete je jeho schopnost nechat uživatele kombinovat své operátory s vlastním nebo cizím kódem prostřednictvím UDF. Až do verze 0.7 musí být všechny UDF napsány v jazyce Java a jsou implementovány jako třídy Java. To usnadňuje přidávání nových UDF do Pig napsáním třídy Java a informováním Pig o souboru JAR.



Samotné prase je dodáváno s některými UDF. Před verzí 0.8 to byla velmi omezená sada pouze se standardními agregačními funkcemi SQL a několika dalšími. V 0.8 bylo přidáno velké množství standardních UDF zpracování řetězců, matematiky a komplexního typu.

Co je to prasátko?

Piggybank je sbírka uživatelsky přispěných UDF, která je vydána společně s Pig. UDF Piggybank nejsou zahrnuty v Pig JAR, takže je musíte zaregistrovat ručně ve svém skriptu. Můžete také napsat vlastní UDF nebo použít ty, které napsali jiní uživatelé.

Evální funkce

Třída UDF rozšiřuje třídu EvalFunc, která je základem pro všechny funkce Eval. Všechny vyhodnocovací funkce rozšiřují třídu Java „org.apache.pig.EvalFunc. „Je parametrizován návratovým typem UDF, což je v tomto případě řetězec Java. Základní metoda v této třídě je ‚exec '. První řádek kódu označuje, že funkce je součástí balíčku myudfs.



Trvá jeden záznam a vrátí jeden výsledek, který bude vyvolán pro každý záznam, který projde potrubím provádění. Trvá n-tici, která obsahuje všechna pole, která skript předá vašemu UDF jako vstup. Potom vrátí typ, kterým jste parametrizovali EvalFunc.

Tato funkce je vyvolána u každé vstupní n-tice. Vstupem do funkce je n-tice se vstupními parametry v pořadí, v jakém jsou předány funkci ve skriptu Pig. V níže uvedeném příkladu má funkce jako vstup řetězec. Následující funkce převede řetězec z malých na velká. Nyní, když je funkce implementována, je třeba ji zkompilovat a zahrnout do JAR.

balíček myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple veřejná třída UPPER rozšiřuje EvalFunc {public String exec (vstup Tuple) vyvolá 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)}}}

Souhrnné funkce:

Agregované funkce jsou dalším běžným typem funkce Eval. Agregační funkce se obvykle používají pro seskupená data. Funkce Aggregate vezme vak a vrátí skalární hodnotu. Zajímavou a cennou vlastností mnoha funkcí agregace je, že je lze vypočítat inkrementálně distribuovaným způsobem. Ve světě Hadoop to znamená, že částečné výpočty lze provádět pomocí Map a Combiner a konečný výsledek lze vypočítat pomocí Reduceru.

Je velmi důležité zajistit, aby agregační funkce, které jsou algebraické, byly implementovány jako takové. Mezi příklady tohoto typu patří integrované funkce POČET, MIN, MAX a PRŮMĚR.

POČET je příkladem algebraické funkce, kde můžeme spočítat počet prvků v podmnožině dat a poté spočítat počty, abychom vytvořili konečný výstup. Podívejme se na implementaci funkce 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 ()} statická veřejná třída Initial extends EvalFunc {public Tuple exec (Tuple input) throws IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} statická veřejná třída Intermed rozšiřuje EvalFunc {public Tuple exec (vstup Tuple) hodí IOException {návrat TupleFactory.getInstance (). newTuple (sum (input))}} statická veřejná třída Final rozšiřuje EvalFunc {public Tuple exec (vstup Tuple) hodí IOException {return sum (input)}} static protected Long count (Tuple input) throws ExecException {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () else if (values instanceof Map) vrátí nové Long (((Map) hodnoty)). size ())} staticky chráněný 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 ( ) součet + = (dlouhý) t.get (0)} návratový součet}}

COUNT implementuje algebraické rozhraní, které vypadá takto:

veřejné rozhraní Algebraické {public String getInitial () public String getIntermed () public String getFinal ()}

Aby byla funkce algebraická, musí implementovat algebraické rozhraní, které se skládá z definice tří tříd odvozených od EvalFunc. Smlouva spočívá v tom, že execfunction třídy Initial je volána jednou a je předána původní vstupní n-tici. Jeho výstupem je n-tice, která obsahuje částečné výsledky. Funkce exec třídy Intermed může být volána nula nebo vícekrát a jako svůj vstup vezme n-tici, která obsahuje částečné výsledky vytvořené třídou Initial nebo předchozími vyvoláními třídy Intermed a vytváří n-tici s jiným částečným výsledkem. Nakonec se vyvolá funkce exec třídy Final, která dává konečný výsledek jako skalární typ.

Funkce filtru:

Funkce filtru jsou Evální funkce, které vrací logickou hodnotu. Lze jej použít kdekoli, kde je vhodný logický výraz, včetně operátoru FILTER nebo výrazu Bincond. Apache Pig úplně nepodporuje logickou hodnotu, takže funkce filtru se nemohou objevit v příkazech, jako je například „Foreach“, kde jsou výsledky odesílány jinému operátorovi. Funkce filtru však lze použít v příkazech filtru.

Následující příklad implementuje funkci IsEmpty:

náhodná třída v java příkladu
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 / ** * Určete, zda je taška nebo mapa prázdná. * / 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 = 'Nelze otestovat' + DataType.findTypeName (values) + 'na prázdnotu.' hodit novou ExecException (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}