Pig UDF - 将动态模式作为一组字段(不是元组)返回

时间:2015-08-18 06:19:02

标签: apache-pig jython user-defined-functions

在GROUP BY + FLATTEN之后,我有一个带命名空间的数据:

DESCRIBE users;
users: {user_id: int, group_id: int, registration_timestamp: int}

users_with_namespace = FOREACH (GROUP users BY group_id) {
    first_to_latest = ORDER users BY registration_timestamp ASC;
    first_user = LIMIT first_to_latest 1;
    GENERATE FLATTEN(first_user);
};

DESCRIBE users_with_namespace;
users_with_namespace: {first_user::user_id: int, first_user::group_id: int, first_user::registration_timestamp: int}

我希望能够做到这样的事情:

users = myudf.strip_namespace(users_with_namespace);

或(因为,似乎不可能):

users = FOREACH (GROUP users_with_namespaceALL) 
GENERATE myudf.strip_namespace(users_with_namespace);

结果为:

> DESCRIBE users;
users: {user_id: int, registration_timestamp: int}

我已经编写了一个Jython Pig UDF,它应该删除任何命名空间的字段名称,但我似乎无法从我的UDF中返回一组字段。只有Bag / Tuple / Single字段是可能的,这样我就得到了这样的结果:

DESCRIBE users;
users: {t: (user_id: int, registration_timestamp: int)}

有没有办法省略'并返回一个列表/一组字段?我的UDF看起来像这样:

@outputSchemaFunction("tupleSchema")
def strip_namespace(input):
    return input


@schemaFunction("tupleSchema")
def tupleSchema(input):
    fields = []
    dt = []
    for i in input.getField(0).schema.getFields():
        for field in i.schema.getFields():
            fields.append(field.alias.split("::")[-1])
            dt.append(field.type)
    return SchemaUtil.newTupleSchema(fields, dt)

到目前为止,我已经

FOREACH .. GENERATE namespace::field as field, ...

去除名称空间,但这种方法对于包含许多字段的数据集来说非常繁琐。

1 个答案:

答案 0 :(得分:3)

不幸的是你不能,至少现在不行。问题正是你所说的:现在你只能返回一个元组,一个袋或一个字段。我创建了一个JIRA issue以允许在2个月前为此方案返回多个字段,但尚未回复...

我真的希望他们将来能够实现这一点,因为当你必须执行许多连接时,最终会有更多FOREACH语句来重命名字段而不是实际代码。