我假设您正在输入的 $0FLATTEN
是u
一个元组。
总体问题是j
仅引用元组中的第一个映射。为了得到你想要的输出,你必须将每个元组转换成一个包,然后FLATTEN
是它。
如果您知道每个元组最多有两个映射,您可以这样做:
-- My B is your u
B = FOREACH A GENERATE (tuple(map[],map[]))$0#'experiences' AS T ;
B2 = FOREACH B GENERATE FLATTEN(TOBAG(T.$0, T.$1)) AS j ;
C = foreach B2 generate j#'id', j#'description' ;
如果您不知道元组中有多少字段,那么这将更加困难。
注意:这适用于猪 0.10。
对于具有未定义数量的映射的元组,我能想到的最佳答案是使用 UDF 来解析字节数组:
myudf.py
@outputSchema('vals: {(val:map[])}')
def foo(the_input):
# This converts the indeterminate number of maps into a bag.
foo = [chr(i) for i in the_input]
foo = ''.join(foo).strip('()')
out = []
for f in foo.split('],['):
f = f.strip('[]')
out.append(dict((k, v) for k, v in [ i.split('#') for i in f.split(',')]))
return out
我的脚本.pig
register 'myudf.py' using jython as myudf ;
B = FOREACH A GENERATE FLATTEN($0#'experiences') ;
T1 = FOREACH B GENERATE FLATTEN(myudf.foo($0)) AS M ;
T2 = FOREACH T1 GENERATE M#'id', M#'description' ;
但是,这依赖于这样一个事实,即#
、,
或],[
不会出现在映射的任何键或值中。
注意:这适用于猪 0.11。
因此,在这种情况下,pig 如何处理 python UDF 的输入似乎发生了变化。bytearray 不是 bytearray 的输入foo
,而是自动转换为适当的类型。在这种情况下,它使一切变得更加容易:
myudf.py
@outputSchema('vals: {(val:map[])}')
def foo(the_input):
# This converts the indeterminate number of maps into a bag.
out = []
for map in the_input:
out.append(map)
return out
我的脚本.pig
register 'myudf.py' using jython as myudf ;
# This time you should pass in the entire tuple.
B = FOREACH A GENERATE $0#'experiences' ;
T1 = FOREACH B GENERATE FLATTEN(myudf.foo($0)) AS M ;
T2 = FOREACH T1 GENERATE M#'id', M#'description' ;