apache pig:组操作后剥离命名空间前缀(::)

webghufk  于 2021-06-21  发布在  Pig
关注(0)|答案(2)|浏览(290)

在我的数据处理中,一种常见的模式是按一组列进行分组,应用过滤器,然后再次展平。例如:

  1. my_data_grouped = group my_data by some_column;
  2. my_data_grouped = filter my_data_grouped by <some expression>;
  3. my_data = foreach my_data_grouped flatten(my_data);

问题是如果 my_data 以类似(c1,c2,c3)的模式开始此操作之后,它将具有类似(mydata::c1,mydata::c2,mydata::c3)的模式。如果列是唯一的,有没有办法轻松去掉“mydata::”前缀?
我知道我可以这样做:

  1. my_data = foreach my_data generate c1 as c1, c2 as c2, c3 as c3;

然而,对于具有大量列的数据集来说,这变得很难维护,对于具有可变列的数据集来说,这是不可能的。

zengzsys

zengzsys1#

如果架构中的所有字段都有相同的前缀集(例如group1::id、group1::amount等),则在引用特定字段时可以忽略前缀(仅将它们引用为id、amount等)
或者,如果您仍然希望去掉一个前缀级别的模式,您可以使用如下自定义项:

  1. public class RemoveGroupFromTupleSchema extends EvalFunc<Tuple> {
  2. @Override
  3. public Tuple exec(Tuple input) throws IOException {
  4. Tuple result = input;
  5. return result;
  6. }
  7. @Override
  8. public Schema outputSchema(Schema input) throws FrontendException {
  9. if(input.size() != 1) {
  10. throw new RuntimeException("Expected input (tuple) but input does not have 1 field");
  11. }
  12. List<Schema.FieldSchema> inputSchema = input.getFields();
  13. List<Schema.FieldSchema> outputSchema = new ArrayList<Schema.FieldSchema>(inputSchema);
  14. for(int i = 0; i < inputSchema.size(); i++) {
  15. Schema.FieldSchema thisInputFieldSchema = inputSchema.get(i);
  16. String inputFieldName = thisInputFieldSchema.alias;
  17. Byte dataType = thisInputFieldSchema.type;
  18. String outputFieldName;
  19. int findLoc = inputFieldName.indexOf("::");
  20. if(findLoc == -1) {
  21. outputFieldName = inputFieldName;
  22. }
  23. else {
  24. outputFieldName = inputFieldName.substring(findLoc+2);
  25. }
  26. Schema.FieldSchema thisOutputFieldSchema = new Schema.FieldSchema(outputFieldName, dataType);
  27. outputSchema.set(i, thisOutputFieldSchema);
  28. }
  29. return new Schema(outputSchema);
  30. }
  31. }
展开查看全部
hmtdttj4

hmtdttj42#

您可以将'as'语句与'foreach'放在同一行。

  1. my_data_grouped = group my_data by some_column;
  2. my_data_grouped = filter my_data_grouped by <some expression>;
  3. my_data = FOREACH my_data_grouped FLATTEN(my_data) AS (c1, c2, c3);

但是,这与在两行上执行相同,并不能缓解“具有可变列的数据集”的问题。

相关问题