Передать отношение в UDF PIG при использовании FOREACH для другого отношения? - PullRequest
0 голосов
/ 24 июля 2010

Мы используем Pig 0.6 для обработки некоторых данных.Одним из столбцов наших данных является разделенный пробелами список идентификаторов (например: 35 521 225).Мы пытаемся сопоставить один из этих идентификаторов с другим файлом, который содержит 2 столбца сопоставлений (например, столбец 1 - наши данные, столбец 2 - данные третьих сторон):

35 6009
521 21599
225 51991
12 6129

Мы написали UDF, который принимает значение столбца (т. Е. «35 521 225») и сопоставления из файла.Затем мы разделяем значение столбца и перебираем каждое из них и возвращаем первое сопоставленное значение из переданных отображений (думая, что это будет логически работать).

Мы загружаем данные в PIG следующим образом:

data = LOAD 'input.txt' USING PigStorage() AS (name:chararray, category:chararray);

mappings = LOAD 'mappings.txt' USING PigStorage() AS (ourId:chararray, theirId:chararray);

Тогда наша генерация будет:

output = FOREACH data GENERATE title, com.example.ourudf.Mapper(category, mappings);

Однако мы получаем ошибку:
'во время синтаксического анализа возникла ошибка: неверные сопоставления псевдонимов в [data :: title: chararray, data :: category, chararray] `

Похоже, что Pig пытается найти столбец с именем" mappings«на наших исходных данных.Который, если конечно нет.Есть ли способ передать отношение, загруженное в UDF?

Есть ли способ, которым тип карты в PIG поможет нам здесь?Или нам нужно каким-то образом объединить значения?

РЕДАКТИРОВАТЬ: Чтобы быть более конкретным - мы не хотим отображать ВСЕ идентификаторы категории на сторонние идентификаторы.Мы просто хотели нанести на карту первый.UDF будет перебирать список идентификаторов наших категорий и вернется, когда найдет первое сопоставленное значение.Поэтому, если входные данные выглядят так:

someProduct \ t35 521 225

, результат будет:
someProduct \ t6009

1 Ответ

2 голосов
/ 25 сентября 2010

Я не думаю, что вы можете сделать это в ожидании в Pig.

Решение, похожее на то, что вы хотели сделать, - это загрузить файл отображения в UDF и затем обработать каждую запись в FOREACH.,Пример доступен в PiggyBank LookupInFiles .Рекомендуется использовать DistributedCache вместо копирования файла непосредственно из DFS.

DEFINE MAP_PRODUCT com.example.ourudf.Mapper('hdfs://../mappings.txt');

data = LOAD 'input.txt' USING PigStorage() AS (name:chararray, category:chararray);

output = FOREACH data GENERATE title, MAP_PRODUCT(category);

Это будет работать, если файл сопоставления не слишком большой.Если он не помещается в памяти, вам придется разделить файл сопоставления и запустить сценарий несколько раз или настроить схему файла сопоставления, добавив номер строки и используя собственное объединение и вложенный FOREACH ORDER BY / LIMIT1 за каждый продукт.

...