Apache Pig pruža opsežnu podršku za korisnički definirane funkcije (UDF) kao način određivanja prilagođene obrade. UDF-ovi svinja trenutno se mogu izvršiti na tri jezika: Java, Python, JavaScript i Ruby. Najopsežnija podrška pruža se za Java funkcije.
Java UDF-ovi mogu se pozivati na više načina. Najjednostavniji UDF može samo proširiti EvalFunc, što zahtijeva samo implementaciju exec funkcije. Svaki Eval UDF to mora provesti. Osim toga, ako je funkcija algebarska, može implementirati algebarsko sučelje da bi značajno poboljšala izvedbu upita.
Važnost UDF-ova u svinji:
Svinja omogućuje korisnicima kombiniranje postojećih operatora sa vlastitim ili tuđim kodom putem UDF-ova. Prednost Pig-a je njegova sposobnost da korisnicima omogući kombiniranje njegovih operatora sa svojim ili tuđim kodom putem UDF-ova. Do verzije 0.7, svi UDF-ovi moraju biti napisani na Javi i implementirani kao Java klase. To olakšava dodavanje novih UDF-ova Pig-u pisanjem Java klase i informiranjem Pig-a o JAR datoteci.
Svinja sama dolazi s nekim UDF-ovima. Prije verzije 0.8, bio je vrlo ograničen skup sa samo standardnim SQL skupnim funkcijama i nekoliko drugih. U 0.8 dodan je velik broj standardnih UDF-ova za obradu nizova, matematiku i složeni tip.
java deklarira niz objekata
Što je Piggybank?
Piggybank je zbirka korisničkih UDF-ova koja se objavljuje zajedno s Pigom. UDF-ovi Piggybank nisu uključeni u PAR JAR, tako da ih morate ručno registrirati u svojoj skripti. Također možete pisati vlastite UDF-ove ili koristiti one koje su napisali drugi korisnici.
Eval funkcije
Klasa UDF proširuje klasu EvalFunc koja je osnova za sve funkcije Eval. Sve funkcije procjene proširuju Java klasu ‘org.apache.pig.EvalFunc. ‘Parametrizira se s vrstom povratka UDF-a koji je u ovom slučaju Java String. Osnovna metoda u ovoj klasi je ‘exec.’ 1. redak koda označava da je funkcija dio paketa myudfs.
Potreban je jedan zapis i vraća se jedan rezultat, koji će se pozvati za svaki zapis koji prolazi kroz cjevovod izvršenja. Potrebna je korpica koja sadrži sva polja koja skripta prosljeđuje na vaš UDF kao ulaz. Zatim vraća vrstu pomoću koje ste parametrirali EvalFunc.
Ova se funkcija poziva na svakom ulaznom kanalu. Ulaz u funkciju je skup s ulaznim parametrima onim redoslijedom kojim se prosljeđuju funkciji u Pig skripti. U primjeru prikazanom dolje, funkcija uzima string kao ulaz. Sljedeća funkcija pretvara niz iz malog u velika slova. Sada kada je funkcija implementirana, treba je sastaviti i uključiti u JAR.
paket myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple javna klasa UPPER proširuje EvalFunc {javni niz exec (Tuple input) baca IOException {if (input == null || input.size () == 0) return null try {String str = (String) input.get (0) return str.toUpperCase ()} catch (Iznimka e) {baciti novi IOException ('Uhvaćen redak obrade ulaznog retka', e)}}}
Zbirne funkcije:
Zbirne funkcije su još jedan uobičajeni tip Evalovih funkcija. Zbirne funkcije obično se primjenjuju na grupirane podatke. Funkcija agregiranja uzima vreću i vraća skalarnu vrijednost. Zanimljiva i vrijedna značajka mnogih agregatnih funkcija je ta da se mogu računati inkrementalno na raspodijeljeni način. U Hadoop svijetu to znači da djelomična izračunavanja mogu izvršiti Map and Combiner, a konačni rezultat može izračunati Reduktor.
Vrlo je važno osigurati da se skupne funkcije koje su algebarske implementiraju kao takve. Primjeri ove vrste uključuju ugrađene COUNT, MIN, MAX i AVERAGE.
RAČUNATI je primjer algebarske funkcije gdje možemo izbrojati broj elemenata u podskupinu podataka, a zatim zbrojiti brojeve kako bismo dobili konačni izlaz. Pogledajmo implementaciju funkcije COUNT:
javna klasa COUNT se proširuje EvalFunc implementira algebarski {javni Long exec (Tuple input) baca 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) baca IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} statička javna klasa Intermed proširuje EvalFunc {javni Tuple exec (ulaz Tuple) baca IOException {return TupleFactory.getInstance (). newTuple (zbroj (ulaz))}} statička javna klasa Final extends EvalFunc {javni Tuple exec (ulaz Tuple) IOException {povratna suma (ulaz)}} statički zaštićen Long count (Tuple input) baca ExecException {Vrijednosti objekta = input.get (0) if (values instanceof DataBag) return ((DataBag) values) .size () else if (values instanceof Map) vraća nove Long (((Map) vrijednosti) .size ())} statički zaštićeni Long sum (Tuple i nput) baca ExecException, NumberFormatException {DataBag values = (DataBag) input.get (0) long sum = 0 for (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) zbroj + = (dugi) t.get (0)} povratni zbroj}}
COUNT implementira algebarsko sučelje koje izgleda ovako:
javno sučelje Algebarski {javni String getInitial () javni String getIntermed () javni String getFinal ()}
Da bi funkcija bila algebarska, treba implementirati algebarsko sučelje koje se sastoji od definicije triju klasa izvedenih iz EvalFunca. Ugovor je da se izvršna funkcija početne klase poziva jednom i prosljeđuje izvornom ulaznom tupleu. Njegov je izlaz skup koji sadrži djelomične rezultate. Exec funkcija intermedirane klase može se pozvati nula ili više puta i uzima kao ulaz skup koji sadrži djelomične rezultate proizvedene od početne klase ili prethodnih poziva klase Intermed i daje tuple s drugim djelomičnim rezultatom. Konačno, poziva se exec funkcija klase Final i daje konačni rezultat kao skalarni tip.
Funkcije filtra:
Funkcije filtra su Eval funkcije koje vraćaju logičku vrijednost. Može se koristiti bilo gdje gdje je prikladan logički izraz, uključujući operator FILTER ili Bincond izraz. Apache Pig ne podržava logički logički, tako da se funkcije filtra ne mogu pojaviti u izrazima kao što je „Foreach“, gdje se rezultati prenose na drugi operator. Međutim, funkcije filtra mogu se koristiti u izjavama filtra.
Primjer u nastavku implementira funkciju 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.DataBataBata import org.apache.pig.data.Tuple import org.apache.pig.data.DataType / ** * Utvrdite jesu li vreća ili karta prazne. * / javna klasa IsEmpty proširuje FilterFunc {@Override javni logički exec (Tuple input) baca IOException {try {Object values = input.get (0) if (values instanceof DataBag) return ((DataBag) values) .size () == 0 else if (vrijednosti instanceof Map) return ((Map) values) .size () == 0 else {int errCode = 2102 String msg = 'Nije moguće testirati' + DataType.findTypeName (values) + 'na prazninu.' baci novi ExecException (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}