Apache Pig UDF: deel 1 - Eval-, aggregatie- en filterfuncties



Dit bericht beschrijft over Apache Pig UDF - Eval-, Aggregate & Filter-functies. Bekijk de Eval-, Aggregate- & Filter-functies.

Apache Pig biedt uitgebreide ondersteuning voor door de gebruiker gedefinieerde functies (UDF's) als een manier om aangepaste verwerking te specificeren. Pig UDF's kunnen momenteel in drie talen worden uitgevoerd: Java, Python, JavaScript en Ruby. De meest uitgebreide ondersteuning wordt geboden voor Java-functies.





c ++ sorteermatrix

Java UDF's kunnen op verschillende manieren worden aangeroepen. De eenvoudigste UDF kan EvalFunc gewoon uitbreiden, waarvoor alleen de exec-functie moet worden geïmplementeerd. Elke Eval UDF moet dit implementeren. Bovendien, als een functie algebraïsch is, kan deze een algebraïsche interface implementeren om de queryprestaties aanzienlijk te verbeteren.

Belang van UDF's bij varkens:

Met Pig kunnen gebruikers bestaande operators combineren met hun eigen code of die van anderen via UDF's. Het voordeel van Pig is de mogelijkheid om gebruikers zijn operators te laten combineren met hun eigen code of die van anderen via UDF's. Tot en met versie 0.7 moeten alle UDF's in Java zijn geschreven en worden geïmplementeerd als Java-klassen. Dit maakt het gemakkelijker om nieuwe UDF's aan Pig toe te voegen door een Java-klasse te schrijven en Pig te informeren over het JAR-bestand.



Pig zelf wordt geleverd met enkele UDF's. Vóór versie 0.8 was het een zeer beperkte set met alleen de standaard SQL-aggregatiefuncties en een paar andere. In 0.8 is een groot aantal standaard string-processing, math en complex-type UDFs toegevoegd.

Wat is een spaarpot?

Piggybank is een verzameling door gebruikers bijgedragen UDF's die samen met Pig wordt uitgebracht. Piggybank UDF's zijn niet inbegrepen in de Pig JAR, dus u moet ze handmatig in uw script registreren. U kunt ook uw eigen UDF's schrijven of deze gebruiken die door andere gebruikers zijn geschreven.

Eval-functies

De UDF-klasse is een uitbreiding van de EvalFunc-klasse die de basis vormt voor alle Eval-functies. Alle evaluatiefuncties breiden de Java-klasse ‘org.apache.pig.EvalFunc uit. ‘Het is geparametriseerd met het retourtype van de UDF, wat in dit geval een Java-string is. De kernmethode in deze klasse is ‘exec.’ De eerste regel van de code geeft aan dat de functie een onderdeel is van het myudfs-pakket.



Het duurt één record en retourneert één resultaat, dat wordt aangeroepen voor elk record dat door de uitvoeringspijplijn gaat. Er is een tuple voor nodig, die alle velden bevat die het script als invoer naar uw UDF doorgeeft. Het geeft dan het type terug waarmee u EvalFunc hebt geparametriseerd.

Deze functie wordt op elk invoertupel aangeroepen. De invoer in de functie is een tuple met invoerparameters in de volgorde waarin ze worden doorgegeven aan de functie in het Pig-script. In het onderstaande voorbeeld neemt de functie een string als invoer. De volgende functie converteert de tekenreeks van kleine letters naar hoofdletters. Nu de functie is geïmplementeerd, moet deze worden gecompileerd en opgenomen in een JAR.

pakket myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data.Tuple public class UPPER breidt EvalFunc {public String exec (Tuple input) uit met IOException {if (input == null || input.size () == 0) retourneer null probeer {String str = (String) input.get (0) retourneer str.toUpperCase ()} catch (uitzondering e) {throw nieuwe IOException ('Gevangen exception processing input row', e)}}}

Geaggregeerde functies:

Geaggregeerde functies zijn een ander veel voorkomend type Eval-functie. Geaggregeerde functies worden meestal toegepast op gegroepeerde gegevens. De Aggregate-functie pakt een bag en retourneert een scalaire waarde. Een interessant en waardevol kenmerk van veel Aggregate-functies is dat ze incrementeel op een gedistribueerde manier kunnen worden berekend. In de Hadoop-wereld betekent dit dat de gedeeltelijke berekeningen kunnen worden gedaan door de kaart en combiner en het uiteindelijke resultaat kan worden berekend door de reductor.

wat is een tostring-methode in java

Het is erg belangrijk om ervoor te zorgen dat Aggregate-functies die algebraïsch zijn, als zodanig worden geïmplementeerd. Voorbeelden van dit type zijn de ingebouwde COUNT, MIN, MAX en AVERAGE.

AANTAL is een voorbeeld van een algebraïsche functie waarbij we het aantal elementen in een subset van de gegevens kunnen tellen en vervolgens de tellingen kunnen optellen om een ​​uiteindelijke uitvoer te produceren. Laten we eens kijken naar de implementatie van de COUNT-functie:

public class COUNT breidt EvalFunc implementeert Algebraic {public Long exec (Tuple input) gooit 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 ()} statische public class Initial breidt EvalFunc uit {public Tuple exec (Tuple input) gooit IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} statische public class Intermed breidt EvalFunc uit {public Tuple exec (Tuple input) gooit IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} statische public class Final breidt EvalFunc uit {public Tuple exec (Tuple input) gooit IOException {return sum (input)}} statisch beveiligd Lange telling (Tuple-invoer) genereert ExecException {Objectwaarden = input.get (0) if (waarden instantie van DataBag) retourneren ((DataBag) waarden) .size () anders if (waarden instantie van kaart) retourneert nieuwe Long (((Map) waarden) .size ())} statisch beschermd Long sum (Tuple i nput) gooit ExecException, NumberFormatException {DataBag-waarden = (DataBag) input.get (0) long sum = 0 voor (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) som + = (Long) t.get (0)} retour som}}

COUNT implementeert een algebraïsche interface die er als volgt uitziet:

openbare interface Algebraic {public String getInitial () public String getIntermed () public String getFinal ()}

Om een ​​functie algebraïsch te laten zijn, moet deze een algebraïsche interface implementeren die bestaat uit een definitie van drie klassen afgeleid van EvalFunc. Het contract is dat de uitvoering van de Initial-klasse één keer wordt aangeroepen en wordt doorgegeven aan het oorspronkelijke invoertupel. De uitvoer is een tuple die gedeeltelijke resultaten bevat. De exec-functie van de Intermed-klasse kan nul of meer keer worden aangeroepen en neemt als invoer een tuple die gedeeltelijke resultaten bevat die zijn geproduceerd door de Initial-klasse of door eerdere aanroepen van de Intermed-klasse en produceert een tuple met een ander gedeeltelijk resultaat. Ten slotte wordt de exec-functie van de klasse Final genoemd en geeft het eindresultaat als een scalair type.

Filterfuncties:

Filterfuncties zijn Eval-functies die een Booleaanse waarde retourneren. Het kan overal worden gebruikt waar een Booleaanse uitdrukking geschikt is, inclusief de FILTER-operator of Bincond-uitdrukking. Apache Pig ondersteunt Boolean niet volledig, dus filterfuncties kunnen niet verschijnen in instructies zoals ‘Foreach’, waar de resultaten worden uitgevoerd naar een andere operator. Filterfuncties kunnen echter worden gebruikt in filterinstructies.

is hadoop gemakkelijk te leren

Het onderstaande voorbeeld implementeert de functie IsEmpty:

importeer java.io.IOException importeer java.util.Map importeer org.apache.pig.FilterFunc importeer org.apache.pig.PigException importeer org.apache.pig.backend.executionengine.ExecException importeer org.apache.pig.data.DataBag import org.apache.pig.data.Tuple import org.apache.pig.data.DataType / ** * Bepaal of een tas of kaart leeg is. * / public class IsEmpty breidt FilterFunc uit {@Override public Boolean exec (Tuple input) genereert IOException {try {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () == 0 else if (values ​​instanceof Map) retourneert ((Map) waarden) .size () == 0 else {int errCode = 2102 String msg = 'Kan een' + DataType.findTypeName (waarden) + 'niet testen op leegte.' gooi nieuwe ExecException (msg, errCode, PigException.BUG)}} catch (ExecException ee) {gooi ee}}}