目前我有一个简单的猪脚本,它从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的值(假设它们都是String
s)
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
....
}
无论如何,我可以通过它的名字得到一个字段的值吗?例如,如果我需要得到10个字段,除了从0到9执行input.get(i)
之外别无他法吗?
我是猪的新手,所以我很想知道为什么会这样。是否有类似tuple.getByFieldName('Field Name')
的内容?
答案 0 :(得分:4)
这是不可能的,允许它也不是很好的设计。 Pig字段名称就像变量名称。它们允许您为某些内容提供令人难忘的名称,让您深入了解其含义。如果在UDF中使用这些名称,则强制每个使用UDF的Pig脚本都遵循相同的命名方案。如果您稍后决定要稍微改变一下您的变量,则无法在其名称中反映出这一点,因为UDF将不再起作用。
从UDF中的输入元组读取数据的代码就像一个函数声明。它建立了如何处理函数的每个参数。
如果您真的希望能够这样做,您可以使用TOMAP
内置函数轻松地构建地图,并从地图中读取UDF。由于上述原因,这极大地损害了UDF的可重用性,但它仍然是一个相当简单的解决方法。
答案 1 :(得分:2)
虽然我同意如果使用字段名称会影响功能灵活性,但从技术上讲,可以按名称访问字段。
诀窍是通过inputSchema
使用getInputSchema()
,并从那里获取字段索引和名称之间的映射。您还可以使用outputSchema
参数覆盖inputSchema
并在那里构建映射。然后,您就可以在exec
方法中使用此映射。
答案 2 :(得分:1)
我认为您不能按名称访问字段。你需要一个类似于map的结构来实现它。在Pig的上下文中,即使你不能按名称进行操作,如果输入(加载)的模式被正确定义和一致,你仍然可以依赖于位置。
您可以做的最大限度是验证您在UDF中摄取的字段类型。
另一方面,您可以在UDF中使用实现“outputSchema”来按名称发布其输出。 UDF Manual