syntax - son - ¿Cómo puedo usar el tipo de datos del mapa en Apache Pig?
los comandos de pig latin para la combinación y separación son: (6)
1) Si desea cargar datos del mapa, debería ser como "[programación # SQL, rdbms # Oracle]"
2) Si desea cargar datos de tupla, debería ser como "(first_name_1234, middle_initial_1234, last_name_1234)"
3) Si desea cargar datos de la bolsa, debería ser como "{(proyecto_4567_1), (proyecto_4567_2), (proyecto_4567_3)}"
mi archivo pigtest.csv como este
1234 | [email protected] | (first_name_1234, middle_initial_1234, last_name_1234) | {(project_1234_1), (project_1234_2), (project_1234_3)} | [programming # SQL, rdbms # Oracle] 4567 | [email protected] | (first_name_4567, middle_initial_4567, last_name_4567) | {(project_4567_1), (project_4567_2), (project_4567_3)} | [programming # Java, OS # Linux]
mi esquema:
a = LOAD ''pigtest.csv'' usando PigStorage (''|'') AS (employee_id: int, email: chararray, name: tuple (first_name: chararray, middle_name: chararray, last_name: chararray), project_list: bag {project: tuple ( project_name: chararray)}, skills: map [chararray]);
b = FOREACH a GENERATE employee_id, email, name.first_name, project_list, skills # ''programming'';
volcado b;
Me gustaría usar Apache Pig para construir una gran clave -> asignación de valor, buscar cosas en el mapa e iterar sobre las teclas. Sin embargo, ni siquiera parece haber sintaxis para hacer estas cosas; Revisé el manual, el wiki, el código de muestra, el libro de elefantes, Google e incluso probé a analizar el origen del analizador. Cada ejemplo carga literales de mapas de un archivo ... y luego nunca los usa. ¿Cómo puedes usar los mapas de Pig?
Primero, no parece haber una manera de cargar un archivo CSV de 2 columnas en un mapa directamente. Si tengo un map.csv
simple:
1,2
3,4
5,6
Y trato de cargarlo como un mapa:
m = load ''map.csv'' using PigStorage('','') as (M: []);
dump m;
Obtengo tres tuplas vacías:
()
()
()
Entonces trato de cargar tuplas y luego generar el mapa:
m = load ''map.csv'' using PigStorage('','') as (key:chararray, val:chararray);
b = foreach m generate [key#val];
ERROR 1000: Error during parsing. Encountered " "[" "[ "" at line 1, column 24.
...
Muchas variaciones en la sintaxis también fallan (por ejemplo, generate [$0#$1]
).
OK, entonces envío mi mapa al formato literal del mapa de Pig como map.pig
:
[1#2]
[3#4]
[5#6]
Y cárgalo:
m = load ''map.pig'' as (M: []);
Ahora carguemos algunas claves e intentemos las búsquedas:
k = load ''keys.csv'' as (key);
dump k;
3
5
1
c = foreach k generate m#key; /* Or m[key], or... what? */
ERROR 1000: Error during parsing. Invalid alias: m in {M: map[ ]}
Hrm, OK, tal vez ya que hay dos relaciones involucradas, necesitamos unirnos:
c = join k by key, m by /* ...um, what? */ $0;
dump c;
ERROR 1068: Using Map as key not supported.
c = join k by key, m by m#key;
dump c;
Error 1000: Error during parsing. Invalid alias: m in {M: map[ ]}
Fallar. ¿Cómo me refiero a la clave (o valor) de un mapa? La sintaxis del esquema del mapa no parece permitirle siquiera nombrar la clave y el valor (la lista de correo dice que no hay forma de asignar tipos).
Finalmente, me gustaría poder encontrar todas las claves en mi mapa:
d = foreach m generate ...oh, forget it.
¿El mapa de Pig está medio cocido? ¿Qué me estoy perdiendo?
Actualmente, los mapas de cerdos necesitan la clave de una chararray (cadena) que suministre y no una variable que contenga una cadena. entonces, en la tecla # del mapa, la clave debe ser una cadena constante que usted suministre (por ejemplo: map # ''keyvalue'').
El caso de uso típico de esto es cargar una estructura de datos compleja, uno de los elementos es un par de valores clave y más adelante, en una declaración foreach, puede hacer referencia a un valor particular basado en la clave que le interesa.
Creo que debes pensar en términos de relations y el map es solo un campo de un registro. Luego puede aplicar algunas operations en las relaciones, como unir los datos de los dos conjuntos y el mapeo :
Entrada
$ cat data.txt
1
2
3
4
5
$ cat mapping.txt
1 2
2 4
3 6
4 8
5 10
Cerdo
mapping = LOAD ''mapping.txt'' AS (key:CHARARRAY, value:CHARARRAY);
data = LOAD ''data.txt'' AS (value:CHARARRAY);
-- list keys
mapping_keys =
FOREACH mapping
GENERATE key;
DUMP mapping_keys;
-- join mapping to data
mapped_data =
JOIN mapping BY key, data BY value;
DUMP mapped_data;
Salida
> # keys
(1)
(2)
(3)
(4)
(5)
> # mapped data
(1,2,1)
(2,4,2)
(3,6,3)
(4,8,4)
(5,10,5)
Esta respuesta también podría ayudarlo si solo quiere hacer una simple consulta : pass-a-relation-to-a-pig-udf-when-using-foreach-on-another-relation
En Pig versión 0.10.0 hay una nueva función disponible llamada "TOMAP" ( http://pig.apache.org/docs/r0.10.0/func.html#tomap ) que convierte sus parámetros impares (chararray) en claves y incluso parámetros a valores. Desafortunadamente, no he encontrado que sea tan útil, ya que normalmente trato con dictados arbitrarios de diferentes longitudes y claves.
Me gustaría encontrar una función TOMAP que tomara una tupla como un único argumento, en lugar de una cantidad variable de parámetros, para ser mucho más útil.
Esta no es una solución completa a su problema, pero la disponibilidad de TOMAP le brinda más opciones para construir una solución real.
Gran pregunta! Personalmente no me gustan los Mapas en Pig. Tienen un lugar en los lenguajes de programación tradicionales como Java, C # etc., en donde es realmente útil y rápido buscar una clave en el mapa. Por otro lado, Maps in Pig tiene características muy limitadas.
Como señaló correctamente, no se puede buscar la clave variable en el Mapa en Pig. La clave debe ser constante. por ejemplo, myMap # ''keyFoo'' está permitido pero myMap # $ SOME_VARIABLE no está permitido.
Si lo piensas, no necesitas Map in Pig. Por lo general, se cargan los datos de alguna fuente, se transforman, se unen a otros datos, se filtran, se transforman, etc. JOIN en realidad hace un buen trabajo al buscar las claves variables en los datos. por ejemplo, data1 tiene 2 columnas A y B y data2 tiene 3 columnas X, Y, Z. Si unifica data1 BY A con data2 BY Z, JOIN hace el trabajo de un Map (del lenguaje tradicional) que asigna el valor de la columna Z al valor de la columna B (a través de la columna A). Entonces data1 representa esencialmente un Mapa A -> B.
Entonces, ¿por qué necesitamos Map in Pig?
Por lo general, los datos de Hadoop son los depósitos de diferentes fuentes de datos de los idiomas tradicionales. Si las fuentes de datos originales contienen Mapas, los datos HDFS contendrían un Mapa correspondiente.
¿Cómo se pueden manejar los datos del mapa?
En realidad hay 2 casos de uso:
Las claves del mapa son constantes. por ejemplo, HttpRequest Header data contiene time, server, clientIp como las claves en Map. para acceder al valor de una clave en particular, un caso acceda a ellos con la tecla Constante. por ejemplo, el encabezado # ''clientIp''.
Las claves del mapa son variables. En estos casos, lo más probable es que desee UNIRSE a las claves del Mapa con algún otro conjunto de datos. Por lo general, convierto el Map to Bag usando UDF MapToBag , que convierte los datos del mapa en una bolsa de 2 tuplas de campo (clave, valor). Una vez que los datos del mapa se convierten en una bolsa de tuplas, es fácil unirlos con otros conjuntos de datos.
Espero que esto ayude.
Puede cargar cualquier dato y luego convertir y almacenar en formato de valor de clave para leer para su uso posterior
data = load ''somedata.csv'' using PigStorage('','')
STORE data into ''folder'' using PigStorage(''#'')
y luego leer como datos mapeados.