1

目前我有一个简单的猪脚本,它从 hadoop fs 上的文件中读取,如

my_input = load 'input_file' as (A, B, C)

然后我有另一行代码需要操作字段,例如将它们转换为大写(如在 Pig UDF 教程中)。

我做类似的事情,

manipulated = FOREACH my_input GENERATE myudf.Upper(A, B, C)

现在在我的Upper.java文件中,我知道我可以得到 A、B、C 的值(假设它们都是Strings)

    public String exec(Tuple input) throws IOException
    {
        //yada yada yada
        ....
        String A = (String) input.get(0);
        String B = (String) input.get(1);
        String C = (String) input.get(2);
        //yada yada yada
        ....
   }

无论如何我可以通过名称获取字段的值吗?input.get(i)例如,如果我需要获得 10 个字段,除了从 0 到 9之外没有别的办法吗?

我是 Pig 的新手,所以我很想知道为什么会这样。有类似的东西tuple.getByFieldName('Field Name')吗?

4

3 回答 3

4

这是不可能的,允许它也不是很好的设计。Pig 字段名称类似于变量名称。它们使您可以为某些事物起一个令人难忘的名称,从而使您深入了解其含义。如果您在 UDF 中使用这些名称,您将强制使用 UDF 的每个 Pig 脚本遵循相同的命名方案。如果您稍后决定要稍微不同地考虑变量,则不能在它们的名称中反映这一点,因为 UDF 将不再起作用。

从 UDF 中的输入元组读取数据的代码就像一个函数声明。它确定了如何处理函数的每个参数。

如果您真的希望能够做到这一点,您可以使用TOMAP内置函数轻松构建地图,并从地图中读取您的 UDF。由于上述原因,这极大地损害了 UDF 的可重用性,但它仍然是一个相当简单的解决方法。

于 2013-06-09T02:11:07.463 回答
2

虽然我同意如果使用字段名称会影响功能灵活性,但从技术上讲,可以按名称访问字段。

诀窍是使用inputSchemaavailable throughgetInputSchema()并从那里获取字段索引和名称之间的映射。您还可以使用参数覆盖outputSchema并在那里构建映射。inputSchema然后你就可以在你的exec方法中使用这个映射。

于 2016-09-29T18:51:56.047 回答
1

我认为您不能按名称访问字段。您需要一个类似于 map 的结构来实现这一点。在 Pig 的上下文中,即使您不能通过名称来执行此操作,如果输入(加载)的架构被正确定义且一致,您仍然可以依赖位置。

您最多可以验证您在 UDF 中提取的字段类型。

另一方面,您可以在 UDF 中使用实现“outputSchema”来按名称发布其输出。 UDF 手册

于 2013-06-08T02:21:26.823 回答