Apache Pig UDF: Part 1 - Funcions Eval, Aggregate i Filter



Aquesta publicació descriu Apache Pig UDF: funcions Eval, Aggregate i Filter. Mireu les funcions Eval, Aggregate i Filter.

Apache Pig proporciona un ampli suport per a les funcions definides per l'usuari (UDF) com una forma d'especificar el processament personalitzat. Els UDF Pig es poden executar actualment en tres idiomes: Java, Python, JavaScript i Ruby. El suport més ampli es proporciona per a funcions Java.





Els UDF de Java es poden invocar de diverses maneres. L'UDF més senzill només pot ampliar EvalFunc, que només requereix la implementació de la funció exec. Tot Eval UDF ha d'implementar això. A més, si una funció és algebraica, pot implementar una interfície algebraica per millorar significativament el rendiment de la consulta.

Importància de les UDF en el porc:

Pig permet als usuaris combinar els operadors existents amb el codi propi o aliè mitjançant UDF. L’avantatge de Pig és la seva capacitat per permetre als usuaris combinar els seus operadors amb el codi propi o aliè mitjançant UDF. Fins a la versió 0.7, tots els UDF s'han d'escriure en Java i s'han d'implementar com a classes Java. Això fa que sigui més fàcil afegir nous UDF a Pig escrivint una classe Java i informant Pig sobre el fitxer JAR.



Pig en si inclou alguns UDF. Abans de la versió 0.8, era un conjunt molt limitat amb només les funcions d'agregat SQL estàndard i algunes altres. Al 0,8 es va afegir un gran nombre d’UDF estàndard de processament de cadenes, matemàtiques i de tipus complex.

Què és una guardiola?

Piggybank és una col·lecció d’UDF aportats pels usuaris que s’allibera juntament amb Pig. Els UDF de Piggybank no estan inclosos al Pig JAR, de manera que els heu de registrar manualment al vostre script. També podeu escriure els vostres propis UDF o utilitzar els escrits per altres usuaris.

Funcions Eval

La classe UDF amplia la classe EvalFunc, que és la base per a totes les funcions Eval. Totes les funcions d’avaluació amplien la classe Java ‘org.apache.pig.EvalFunc. ‘Es parametritza amb el tipus de retorn de l’UDF que és una cadena de Java en aquest cas. El mètode bàsic d’aquesta classe és ‘exec.’ La primera línia del codi indica que la funció forma part del paquet myudfs.



Pren un registre i retorna un resultat, que s’invocarà per a cada registre que passi pel canal d’execució. Es necessita una tupla, que conté tots els camps que l'script passa al vostre UDF com a entrada. A continuació, retorna el tipus amb el qual heu parametritzat EvalFunc.

Aquesta funció s'invoca a cada tupla d'entrada. L’entrada a la funció és una tupla amb paràmetres d’entrada en l’ordre en què es passen a la funció de l’escriptura Pig. A l'exemple que es mostra a continuació, la funció pren la cadena com a entrada. La següent funció converteix la cadena de minúscules a majúscules. Ara que la funció està implementada, cal compilar-la i incloure-la en un JAR.

package 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 ('Caught exception processing input input', e)}}}

Funcions agregades:

Les funcions agregades són un altre tipus comú de funció Eval. Les funcions agregades se solen aplicar a les dades agrupades. La funció Agregat agafa una bossa i retorna un valor escalar. Una característica interessant i valuosa de moltes funcions agregades és que es poden calcular incrementalment de manera distribuïda. Al món Hadoop, això significa que els càlculs parcials els poden fer Map i Combiner i que el resultat final pot ser calculat pel Reducer.

És molt important assegurar-se que les funcions agregades que siguin algebraiques s’implementin com a tals. Alguns exemples d’aquest tipus són els COUNT, MIN, MAX i AVERAGE integrats.

COMPTE és un exemple de funció algebraica on podem comptar el nombre d’elements d’un subconjunt de dades i, a continuació, sumar els recomptes per produir una sortida final. Vegem la implementació de la funció COUNT:

public class COUNT amplia EvalFunc implementa Algebraic {public Exec llarg (entrada de tupla) llança IOException {compte de retorn (entrada)} cadena pública getInitial () {retorn Initial.class.getName ()} cadena pública getIntermed () {retorn Intermed.class. getName ()} public String getFinal () {return Final.class.getName ()} static public class Initial estén EvalFunc {public Tuple exec (Tuple input) llança IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} static public class Intermed estén EvalFunc {public Tuple exec (Tuple input) throws IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} static public class Final estén EvalFunc {public Tuple exec (Tuple input) throws IOException {suma de devolució (entrada)}} estàtica protegida Recompte llarg (entrada de tupla) genera ExecException {Valors de l’objecte = input.get (0) if (valors instància de DataBag) retornen ((DataBag) valors) .size () else if (valors instanceof Map) retorna nous valors llargs (((mapa)) .size ())} suma llarga protegida estàticament (tupla i nput) llança ExecException, NumberFormatException {Valors DataBag = (DataBag) input.get (0) suma llarga = 0 per (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) suma + = (Llarga) t.get (0)} suma de devolució}}

COUNT implementa una interfície algebraica que té aquest aspecte:

interfície pública algebraica {public String getInitial () public String getIntermed () public String getFinal ()}

Perquè una funció sigui algebraica, ha d’implementar una interfície algebraica que consisteixi en la definició de tres classes derivades d’EvalFunc. El contracte és que la funció executiva de la classe Initial es crida una vegada i es passa a la tupla d’entrada original. La seva sortida és una tupla que conté resultats parcials. La funció exec de la classe Intermed es pot anomenar zero o més vegades i pren com a entrada una tupla que conté resultats parcials produïts per la classe inicial o per invocacions prèvies de la classe Intermed i que produeix una tupla amb un altre resultat parcial. Finalment, es diu la funció exec de la classe Final i dóna el resultat final com a tipus escalar.

Funcions de filtre:

Les funcions de filtre són funcions Eval que retornen un valor booleà. Es pot utilitzar a qualsevol lloc que sigui adequada una expressió booleana, inclòs l'operador FILTER o l'expressió Bincond. Apache Pig no admet Boolean totalment, de manera que les funcions de filtre no poden aparèixer en sentències com ara 'Foreach', on els resultats es publiquen a un altre operador. Tot i això, les funcions de filtre es poden utilitzar a les sentències de filtre.

com fer un munt a Java

L'exemple següent implementa la funció 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 / ** * Determineu si una bossa o un mapa està buit. * / public class IsEmpty amplia FilterFunc {@Override public Boolean exec (Tuple input) llança IOException {try {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () == 0 else if (instància de valors de mapa) retorna (valors de (mapa)) .size () == 0 else {int errCode = 2102 String msg = 'No es pot provar un' + DataType.findTypeName (valors) + 'per a buit.' llança una nova ExecException (msg, errCode, PigException.BUG)}} captura (ExecException ee) {llença ee}}}