UDF,UDAF y UDTF Apache Hive
Bueno en el post de manejo de Apache Hive aprendimos a usar lo que nos brinda hive como componente, pero que tal si quisiéramos enriquecer a este componente con funciones más poderosas y de la mano del MapReduce ó TEZ de acuerdo con lo que nuestro Hive este funcionando, bueno esto es posible con código y este post lo mostrará creando el código necesario para ciertas funcionalidades y mostrar como hacerlo gracias a tres características custom que nos provee Apache Hive las cuales son las siguientes.
- UDF (User Defined Function)
- UDAF (User Defined Agregation Function)
- UDTF (User Defined Tabular Function)
A lo largo del post mostraré un ejemplo de estas tres funciones dando como base la forma de programar este tipo de funciones para que ustedes puedan realizar las suyas de acuerdo a sus necesidades.
Los ejemplos los trabajaremos con los datasets siguientes que se encuentran en esta página como ejemplo: https://support.spatialkey.com/spatialkey-sample-csv-data/
El proyecto para este post puede descargarse de la siguiente página:
https://github.com/NeoChoosenOne/HIVE_FUNCTIONS
Los ejemplos los trabajaremos con los datasets siguientes que se encuentran en esta página como ejemplo: https://support.spatialkey.com/spatialkey-sample-csv-data/
El proyecto para este post puede descargarse de la siguiente página:
https://github.com/NeoChoosenOne/HIVE_FUNCTIONS
UDF (User Defined Function)
Usualmente este tipo de funciones son para manipular la información en nuestras tablas de manera que podamos hacer "transformaciones sobre la información" por decirlo de alguna manera, este concepto viene heredado de las RDBMS, este tipo de funciones trabaja sobre una columna y regresa una columna como salida.
Ahora procederé a definir de manera formal como es que se puede caracterizar una UDF, con la siguiente definición.

Una vez explicado esto podemos verlo en la práctica, de la siguiente forma, empezaremos creando una tabla en Apache Hive con una columna de la siguiente manera.
Ahora procederé a definir de manera formal como es que se puede caracterizar una UDF, con la siguiente definición.

Una vez explicado esto podemos verlo en la práctica, de la siguiente forma, empezaremos creando una tabla en Apache Hive con una columna de la siguiente manera.
Entonces hemos creado una tabla llamada datos con un campo del tipo STRING que se llama nombre, ahora procedemos a insertarle información en minúsculas de la siguiente manera.
Una vez insertada la información de la manera anterior procedemos a listarla, solo para verificar que la información se agrego de manera correcta.
Una vez que verificamos que la información se ha agregado correctamente, procedemos a crear nuestra UDF, en el link anterior del código a nuestro proyecto llamado hive_functions, podemos observar que en la carpeta target como en los demás códigos contiene un jar llamado hive_functions-0.0.1-SNAPSHOT.jar dentro de este jar ya contiene la UDF definida anteriormente de manera formal en el paquete com.cbds.hive.functions y el nombre de la clase es ToUpperCase con esta clase crearemos una función temporal de la siguiente manera.
En el recuadro rojo podemos encontrar la instrucción para agregar nuestro jar a el classpath de Apache Hive y en el recuadro verde se encuentra la sentencia para crear nuestra función en Apache Hive, una vez realizado estos pasos procederemos a utilizar esta función de la cual esperamos una salida con la columna nombre pero en mayúsculas todos sus registros.
Como podemos ver al usar nuestra función en la columna nombre, el resultado es otra columna con los nombres en mayúsculas.
Ahora bien con nuestra primera definición este ejemplo anterior se puede formalizar de la siguiente manera.

Como podemos ver se ajusta a nuestra definición anterior el ejemplo practico, pero también se definió que se puede realizar una función que vaya de un espacio de columnas de n dimensiones a una columna de una dimensión, bueno a continuación modelare este caso tomando nuestra dimensión n=5.
Para este ejemplo crearé una tabla que modele las calificaciones de diferentes estudiantes en una escuela donde cada estudiante tendrá una tira de materias de 5 asignaturas, las cuales serán Español, Matemáticas, Geografía, Historia e Inglés, entonces procedemos a crear esta tabla en Apache Hive con los siguientes comandos, las calificaciones obviamente son del tipo double suponiendo que se califique en un rango [0,10].
Creamos la tabla con la siguiente sentencia:

Una vez creada nuestra tabla de calificaciones procedemos a insertarle datos con la siguiente sentencia.

Como podemos ver con esto hemos insertado 8 registros, ahora realizamos un select para corroborar que la información ha sido agregada satisfactoriamente.

Cómo podemos ver la información ha sido insertada de forma exitosa, ahora procederemos a usar nuestra nueva UDF, la cual tendrá como función recibir 5 columnas y nos dará como resultado una columna y el resultado de esta columna será la calificación más alta de entre las 5 materias que tienen calificación nuestros registros.
El jar es el mismo que el ejemplo anterior, el que tiene por nombre hive_functions-0.0.1-SNAPSHOT.jar dentro de este jar en el paquete com.cbds.hive.functions y el nombre de la clase es MaxRate con esta clase crearemos una función temporal de la siguiente manera.

Ahora realizamos el mismo paso anterior de agregar un jar y ahora creamos una función llamada MaxCalificacion en Apache Hive, ahora como dije es una función que recibe un vector de columnas de dimensión 5, entonces le enviaremos como entrada un vector con 5 entradas de tipo columna, eso lo muestro a continuación.

Como podemos ver en el recuadro verde se encuentra la sentencia, podemos observar que quiero que me regrese dos columnas, el nombre y el resultado de MaxCalificacion(espanol,matematicas,geografia,historia,ingles) el cual es nuestra función que recibe un vector de dimención 5, con esto retomamos la definición general de como funciona una UDF de manera formal con la definición que se presento al inicio, pero para ejemplificar este ejemplo daré el modelo formal de la siguiente manera.

Como podemos ver esta es la primera definición que se cito al inicio de este apartado de las UDF, pero aplicado a nuestro caso anterior. Pero entonces se preguntarán ¿Qué diferencia tiene crear una UDF en una RDBMS que en Hive?, La respuesta es muy simple, en el siguiente post veremos formas de paralelizar y es que estas UDF en Hive se realizan de forma distribuida, cosa que no hace una RDBMS, osea que la función f la ejecutan m nodos, donde m es el número de mappers que el ResourceManager decide que debe tener ese Job.
Ahora bien con nuestra primera definición este ejemplo anterior se puede formalizar de la siguiente manera.

Como podemos ver se ajusta a nuestra definición anterior el ejemplo practico, pero también se definió que se puede realizar una función que vaya de un espacio de columnas de n dimensiones a una columna de una dimensión, bueno a continuación modelare este caso tomando nuestra dimensión n=5.
Para este ejemplo crearé una tabla que modele las calificaciones de diferentes estudiantes en una escuela donde cada estudiante tendrá una tira de materias de 5 asignaturas, las cuales serán Español, Matemáticas, Geografía, Historia e Inglés, entonces procedemos a crear esta tabla en Apache Hive con los siguientes comandos, las calificaciones obviamente son del tipo double suponiendo que se califique en un rango [0,10].
Creamos la tabla con la siguiente sentencia:

Una vez creada nuestra tabla de calificaciones procedemos a insertarle datos con la siguiente sentencia.

Como podemos ver con esto hemos insertado 8 registros, ahora realizamos un select para corroborar que la información ha sido agregada satisfactoriamente.

Cómo podemos ver la información ha sido insertada de forma exitosa, ahora procederemos a usar nuestra nueva UDF, la cual tendrá como función recibir 5 columnas y nos dará como resultado una columna y el resultado de esta columna será la calificación más alta de entre las 5 materias que tienen calificación nuestros registros.
El jar es el mismo que el ejemplo anterior, el que tiene por nombre hive_functions-0.0.1-SNAPSHOT.jar dentro de este jar en el paquete com.cbds.hive.functions y el nombre de la clase es MaxRate con esta clase crearemos una función temporal de la siguiente manera.

Ahora realizamos el mismo paso anterior de agregar un jar y ahora creamos una función llamada MaxCalificacion en Apache Hive, ahora como dije es una función que recibe un vector de columnas de dimensión 5, entonces le enviaremos como entrada un vector con 5 entradas de tipo columna, eso lo muestro a continuación.

Como podemos ver en el recuadro verde se encuentra la sentencia, podemos observar que quiero que me regrese dos columnas, el nombre y el resultado de MaxCalificacion(espanol,matematicas,geografia,historia,ingles) el cual es nuestra función que recibe un vector de dimención 5, con esto retomamos la definición general de como funciona una UDF de manera formal con la definición que se presento al inicio, pero para ejemplificar este ejemplo daré el modelo formal de la siguiente manera.

Como podemos ver esta es la primera definición que se cito al inicio de este apartado de las UDF, pero aplicado a nuestro caso anterior. Pero entonces se preguntarán ¿Qué diferencia tiene crear una UDF en una RDBMS que en Hive?, La respuesta es muy simple, en el siguiente post veremos formas de paralelizar y es que estas UDF en Hive se realizan de forma distribuida, cosa que no hace una RDBMS, osea que la función f la ejecutan m nodos, donde m es el número de mappers que el ResourceManager decide que debe tener ese Job.
UDAF (User Defined Agregation Function)
Usualmente este tipo de funciones son para realizar operaciones matemáticas, sacar promedios, sumatorias, máximos, mínimos, prácticamente el concepto viene heredado de las RDBMS.
Podemos definir una UDAF de manera más formal de la manera siguiente:

Ahora con esta definición procederemos a realizar un ejercicio que calcule el promedio de ciertos pagos realizados en el siguiente dataset.
El ejemplo que trataré en esta sección de UDAF será una función que realice un agrupamiento por alguna característica y que realice la suma de alguna columna del tipo numérico, para realizar esto utilizaré el dataset llamado Sales transactions lo podemos encontrar en la siguiente imagen.

Una vez que descarguemos este dataset de los post anteriores realizamos la carga a Apache Hive en forma de tabla, en mi caso llame la tabla como udaf_sample y contiene los siguientes campos y tipos, debo aclarar que este archivo contiene un registro con comillas dobles en el campo price, el cuál deberá cambiarse ya que no hace sentido al tratarse de un campo del tipo double.

Ahí se encuentra el nombre de la tabla y el metadato de esta tabla sería el siguiente.

Una vez que contamos con esta información les dejo en el siguiente link al código fuente de nuestra UDAF, el cuál agregaremos de la siguiente manera a Apache Hive.

En el recuadro rojo podemos observar que estamos agregando nuestro jar que contiene las UDAF, UDF y UDTF, podemos hacer un jar como en este caso que contenga las 3 ó un jar para cada caso, eso depende de la persona que las desarrolle.
Una vez agregado el jar al classpath the Apache Hive, debemos definir una función que será temporal y realizará lo que hemos programado en nuestra UDAF, para realizar lo anterior es la sentencia que se encuentra en el recuadro verde, como podemos ver le he dado un nombre a mi función en Hive PromedioFuncion y le mando la clase que esta en nuestro jar llamado hive_functions-0.0.1-SNAPSHOT.jar la cual podemos encontrar en el paquete com.cbds.hive.functions y el nombre de la clase es PromedioUDAF una vez creada la función temporal podemos hacer uso de ella de la siguiente manera.

Como podemos ver estamos haciendo un select y mandando a llamar nuestra función temporal que ya habíamos creado llamada PromedioFuncion, la cual en nuestro código recibe datos del tipo double y la columna price es del tipo double, y mandamos a hacer una agrupación por la columna payment_type, como vemos en la imagen al final nos ha arrojado el promedio de las cuatro formas de pago que hay disponible en este archivo.
Ahora explicaré de forma más formal que es lo que se lleva a acabo en una función como estas en Hive.
Podemos definir una UDAF de manera más formal de la manera siguiente:

Ahora con esta definición procederemos a realizar un ejercicio que calcule el promedio de ciertos pagos realizados en el siguiente dataset.
El ejemplo que trataré en esta sección de UDAF será una función que realice un agrupamiento por alguna característica y que realice la suma de alguna columna del tipo numérico, para realizar esto utilizaré el dataset llamado Sales transactions lo podemos encontrar en la siguiente imagen.

Una vez que descarguemos este dataset de los post anteriores realizamos la carga a Apache Hive en forma de tabla, en mi caso llame la tabla como udaf_sample y contiene los siguientes campos y tipos, debo aclarar que este archivo contiene un registro con comillas dobles en el campo price, el cuál deberá cambiarse ya que no hace sentido al tratarse de un campo del tipo double.

Ahí se encuentra el nombre de la tabla y el metadato de esta tabla sería el siguiente.

Una vez que contamos con esta información les dejo en el siguiente link al código fuente de nuestra UDAF, el cuál agregaremos de la siguiente manera a Apache Hive.

En el recuadro rojo podemos observar que estamos agregando nuestro jar que contiene las UDAF, UDF y UDTF, podemos hacer un jar como en este caso que contenga las 3 ó un jar para cada caso, eso depende de la persona que las desarrolle.
Una vez agregado el jar al classpath the Apache Hive, debemos definir una función que será temporal y realizará lo que hemos programado en nuestra UDAF, para realizar lo anterior es la sentencia que se encuentra en el recuadro verde, como podemos ver le he dado un nombre a mi función en Hive PromedioFuncion y le mando la clase que esta en nuestro jar llamado hive_functions-0.0.1-SNAPSHOT.jar la cual podemos encontrar en el paquete com.cbds.hive.functions y el nombre de la clase es PromedioUDAF una vez creada la función temporal podemos hacer uso de ella de la siguiente manera.

Como podemos ver estamos haciendo un select y mandando a llamar nuestra función temporal que ya habíamos creado llamada PromedioFuncion, la cual en nuestro código recibe datos del tipo double y la columna price es del tipo double, y mandamos a hacer una agrupación por la columna payment_type, como vemos en la imagen al final nos ha arrojado el promedio de las cuatro formas de pago que hay disponible en este archivo.
Ahora explicaré de forma más formal que es lo que se lleva a acabo en una función como estas en Hive.
UDTF (User Defined Tabular Function)
Usualmente este tipo de funciones son funciones que trabajan con una columna de entrada y de salida generan n columnas, a continuación daré una caracterización formal.
Para ejemplificar este tipo de funciones, procederé a crear una tabla con texto separado por pipe y agregaré una numeración entre el 0 y 2 números enteros para hacer referencia que pertenecen a algún tema en especifico.
Creamos nuestra tabla con las siguientes sentencia:

Una vez creada esta tabla, en el buscador que más les agrade busquen textos de temas que les agrade, para realizar este ejercicio, tomaré dos fragmentos de cada tema que escoja, por decir en biotecnología escogeré el siguiente párrafo.
Para ejemplificar este tipo de funciones, procederé a crear una tabla con texto separado por pipe y agregaré una numeración entre el 0 y 2 números enteros para hacer referencia que pertenecen a algún tema en especifico.
Creamos nuestra tabla con las siguientes sentencia:

Una vez creada esta tabla, en el buscador que más les agrade busquen textos de temas que les agrade, para realizar este ejercicio, tomaré dos fragmentos de cada tema que escoja, por decir en biotecnología escogeré el siguiente párrafo.

Como podemos ver en el recuadro rojo es el final de mi texto de la siguiente imagen que esta en el recuadro verde, y le agregamos un pipe y el número 0, este ejemplo no tiene la intención de ser inteligente, ni mucho menos hacer alguna función de IA, es un ejemplo sencillo solo para mostrar la funcionalidad de una UDTF, ya que hive recibe cualquier tipo de estructura, y a lo mejor te gustaría tratar una columna del tipo String y de ella sacar n columnas, para eso es este ejercicio, para ejemplificar con algo sencillo esa acción.

Y así continuaré agregando más textos, serán 2 sentencias por tema.


Bueno, para no llenar esto de imágenes, al final quedaron 6 registros con 3 temas diferentes y con un pipe como delimitador agregando 0 al primer tema, 1 al segundo y 2 al tercero, ahora el propósito de esta UDFT es crear una función que reciba como entrada una columna y nos de como resultado 3 columnas las cuales pertenecerán al tema 0,1 y 2, dependiendo del valor que tenga cada registro de nuestra columna.
Ahora procederemos por agregar el jar correspondiente para que podamos crear nuestra UDTF, como en se llevo a cabo con las UDF y las UDAF, aquí también se utilizará el jar llamado hive_functions-0.0.1-SNAPSHOT.jar en donde encontraremos la clase en el paquete com.cbds.hive.functions y el nombre de la clase es ChooseClassUDTF, entonces procedemos a agregar el jar al classpath de hive, no es necesario que se haga esto las 3 veces como lo hice en este post, ya que el jar contiene las 3, pero esto es en caso de que estén en jar separados o que solo quieran probar un ejemplo en especial.

Ahora procedemos a crear una función con el jar anterior.

Una vez creada la función procederemos a utilizarla con la siguiente sentencia.

No se nota por la longitud de las cadenas, pero con esta función de una columna hemos creado 3, que son la columna de Biotecnología, Universo y Matemáticas, con textos más pequeños la separación deberían ser notorias, las diferentes columnas, ahora procederé a dar la definición formal para este caso en especial de la elección de tema.

Y así continuaré agregando más textos, serán 2 sentencias por tema.


Bueno, para no llenar esto de imágenes, al final quedaron 6 registros con 3 temas diferentes y con un pipe como delimitador agregando 0 al primer tema, 1 al segundo y 2 al tercero, ahora el propósito de esta UDFT es crear una función que reciba como entrada una columna y nos de como resultado 3 columnas las cuales pertenecerán al tema 0,1 y 2, dependiendo del valor que tenga cada registro de nuestra columna.
Ahora procederemos por agregar el jar correspondiente para que podamos crear nuestra UDTF, como en se llevo a cabo con las UDF y las UDAF, aquí también se utilizará el jar llamado hive_functions-0.0.1-SNAPSHOT.jar en donde encontraremos la clase en el paquete com.cbds.hive.functions y el nombre de la clase es ChooseClassUDTF, entonces procedemos a agregar el jar al classpath de hive, no es necesario que se haga esto las 3 veces como lo hice en este post, ya que el jar contiene las 3, pero esto es en caso de que estén en jar separados o que solo quieran probar un ejemplo en especial.

Ahora procedemos a crear una función con el jar anterior.

Una vez creada la función procederemos a utilizarla con la siguiente sentencia.

No se nota por la longitud de las cadenas, pero con esta función de una columna hemos creado 3, que son la columna de Biotecnología, Universo y Matemáticas, con textos más pequeños la separación deberían ser notorias, las diferentes columnas, ahora procederé a dar la definición formal para este caso en especial de la elección de tema.
Comentarios
Publicar un comentario