Как я могу использовать тип данных карты в Apache Pig? - PullRequest
21 голосов
/ 01 ноября 2010

Я бы хотел использовать Apache Pig для построения большого ключа -> отображения значений, поиска объектов на карте и перебора ключей.Тем не менее, даже кажется, что нет синтаксиса для выполнения этих вещей;Я проверил руководство, вики, пример кода, книгу Elephant, Google и даже попытался разобрать исходный текст парсера.Каждый пример загружает литералы карты из файла ... и затем никогда не использует их.Как вы можете использовать карты Свиньи?

Во-первых, кажется, что нет способа загрузить файл CSV с двумя столбцами непосредственно в карту.Если у меня есть простой map.csv:

1,2
3,4
5,6

И я пытаюсь загрузить его как карту:

m = load 'map.csv' using PigStorage(',') as (M: []);
dump m;

Я получаю три пустых кортежа:

()
()
()

Поэтому я пытаюсь загрузить кортежи, а затем сгенерировать карту:

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.
...

Многие вариации синтаксиса также терпят неудачу (например, generate [$0#$1]).

ОК, поэтому я превращаю свою карту в буквальный формат карты Свиньи как map.pig:

[1#2]
[3#4]
[5#6]

И загружаю ее:

m = load 'map.pig' as (M: []);

Теперь давайте загрузимнекоторые ключи и попробуйте поискать:

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[ ]}

Хм, хорошо, возможно, так как в этом участвуют два отношения, нам нужно объединение:

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[ ]}

Fail.Как мне обратиться к ключу (или значению) карты?Синтаксис схемы карты, кажется, не позволяет даже назвать ключ и значение (в списке рассылки сказано, что нет способа назначать типы).

Наконец, я просто хотел бы найти все, что ониключи на моей карте:

d = foreach m generate ...oh, forget it.

Тип карты Свиньи наполовину испечен?Чего мне не хватает?

Ответы [ 6 ]

2 голосов
/ 23 ноября 2011

В настоящее время для свиноводческих карт требуется ключ к предоставленной вами строке (строке), а не переменная, содержащая строку.поэтому в ключе map # ключ должен быть заданной вами константной строкой (например, map # 'keyvalue').

Типичным случаем использования этого является загрузка сложной структуры данных, один из элементов которой являетсяпара ключ-значение, а затем в выражении foreach вы можете ссылаться на конкретное значение на основе интересующего вас ключа.

http://pig.apache.org/docs/r0.9.1/basic.html#map-schema

1 голос
/ 29 мая 2017

1) Если вы хотите загрузить данные карты, это должно выглядеть так: «[program # SQL, rdbms # Oracle]»

2) Если вы хотите загрузить данные кортежа, это должно быть похоже на «(first_name_1234,middle_initial_1234, last_name_1234) "

3) Если вы хотите загрузить данные мешка, они должны выглядеть как" {(project_4567_1), (project_4567_2), (project_4567_3)} "

мой файл pigtest.csvкак это

1234 | emp_1234@company.com | (first_name_1234, middle_initial_1234, last_name_1234) | {(project_1234_1), (project_1234_2), (project_1234_3)} | [программирование # SQL, rdbms # Oracle] 4567 | emp_4567@ company.com | (first_name_4567, middle_initial_4567, last_name_4567) | {(project_4567_1), (project_4567_2), (project_4567_3)} | [программирование # Java, OS # Linux]


моя схема:

a = ЗАГРУЗИТЬ 'pigtest.csv' с использованием PigStorage ('|') AS (employee_id: int, электронная почта: chararray, name: tuple (first_name: chararray, middle_name: chararray, last_name: chararray), project_list: bag {проект: кортеж (имя_проекта: chararray)}, навыки: карта [chararray]);

b =FOREACH a GENERATE employee_id, электронная почта, name.first_name, project_list, навыки # 'программирование';

dump b;

1 голос
/ 20 октября 2015

Отличный вопрос!Я лично не люблю Карты в Свинье.У них есть место в традиционных языках программирования, таких как Java, C # и т. Д., Где действительно удобно и быстро искать ключ на карте.С другой стороны, карты в Pig имеют очень ограниченные возможности.

Как вы правильно заметили, нельзя искать переменную key в Map in Pig.Ключ должен быть постоянным.Например, myMap # 'keyFoo' разрешен, но myMap # $ SOME_VARIABLE не разрешен.

Если вы думаете об этом, вам не нужна Map in Pig.Обычно данные загружаются из какого-либо источника, преобразуются, объединяются с другим набором данных, фильтруются, преобразуются и так далее.JOIN на самом деле хорошо выполняет поиск переменных ключей в данных.например, data1 имеет 2 столбца A и B, а data2 имеет 3 столбца X, Y, Z. Если вы объединяете data1 BY A с data2 BY Z, JOIN выполняет работу с картой (из традиционного языка), которая отображает значение столбца Z на значениестолбца B (через столбец A).Таким образом, data1 по существу представляет карту A -> B.

Так зачем нам карта в Pig?

Обычно данные Hadoop представляют собой дампы различных источников данных из традиционногоязыки.Если исходные источники данных содержат Карты, данные HDFS будут содержать соответствующую Карту.

Как можно обрабатывать данные Карты?

В действительности существует 2 варианта использования:

  1. Ключи карты являются константами.Например, данные заголовка HttpRequest содержат время, сервер, clientIp в качестве ключей на карте.чтобы получить доступ к значению определенного ключа, один случай доступа к ним с помощью постоянного ключа.например, заголовок # 'clientIp'.

  2. Ключи карты являются переменными.В этих случаях вы, скорее всего, захотите объединить ключи карты с другим набором данных.Я обычно конвертирую Map в Bag, используя UDF MapToBag , который преобразует данные карты в Bag из двух кортежей полей (ключ, значение).После преобразования данных карты в пакет кортежей его легко объединить с другими наборами данных.

Надеюсь, это поможет.

1 голос
/ 30 июля 2012

В Pig версии 0.10.0 доступна новая функция под названием "TOMAP" (http://pig.apache.org/docs/r0.10.0/func.html#tomap)), которая преобразует свои нечетные (chararray) параметры в ключи и даже параметры в значения. К сожалению, я не нашел ее в Тем не менее, это будет полезно, поскольку я обычно имею дело с произвольными диктовками различной длины и ключами.

Я бы обнаружил, что функция TOMAP, которая принимает кортеж в качестве единственного аргумента вместо переменного количества параметров, была бы гораздо более полезной.

Это не полное решение вашей проблемы, но наличие TOMAP дает вам еще несколько вариантов для построения реального решения.

0 голосов
/ 06 августа 2018

Вы можете загрузить любые данные, а затем преобразовать и сохранить в формате значения ключа для чтения для дальнейшего использования

data = load 'somedata.csv' using PigStorage(',')
STORE data into 'folder' using PigStorage('#')

, а затем прочитать как сопоставленные данные.

0 голосов
/ 07 декабря 2010

Я думаю, вам нужно думать о отношениях , а карта - это только одно поле одной записи. Затем вы можете применить некоторые операции к отношениям, например, объединить два набора data и mapping :

Input

$ cat data.txt 
1
2
3
4
5
$ cat mapping.txt 
1   2
2   4
3   6
4   8
5   10

Pig

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;

выход

> # keys
(1)
(2)
(3)
(4)
(5)

> # mapped data
(1,2,1)
(2,4,2)
(3,6,3)
(4,8,4)
(5,10,5)

Этот ответ также может помочь вам, если вы просто хотите просто посмотреть : пройти-а-отношение-к-а-свинью-UDF-при-использовании-Еогеасп-на-другой-связи

...