0

我们正在使用 Pig 0.6 来处理一些数据。我们数据的其中一列是以空格分隔的 id 列表(例如:35 521 225)。我们正在尝试将其中一个 id 映射到另一个包含 2 列映射的文件,例如(因此第 1 列是我们的数据,第 2 列是第 3 方数据):

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 试图在我们的原始数据上找到一个名为“映射”的列。如果课程不存在的话。有没有办法传递加载到 UDF 中的关系?

PIG 中的“地图”类型有什么方法可以帮助我们吗?还是我们需要以某种方式加入价值观?

编辑:更具体地说 - 我们不想将所有类别 ID 映射到第 3 方 ID。我们只是想映射第一个。UDF 将遍历我们的类别 ID 列表 - 并在找到第一个映射值时返回。因此,如果输入看起来像:

一些产品\t35 521 225

输出将是:
someProduct\t6009

4

1 回答 1

2

我不认为你可以在 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/LIMIT 1。

于 2010-09-24T20:38:42.100 回答