3

编辑:我将尝试解释我想要做什么。

1行输入看起来像:field1,field2,textfield

现在textfield是一个字符串条目,它是固定数量的字符。我想解析这个字符串以从这些字符中提取子字符串。例如,我想提取前 10 个字符并将其设为字段,提取接下来的 15 个字符并将其设为字段,等等...

那部分很好。问题变成不是每一行都有相同的文本字段规则。基本上field1field2将代表我用来解析该文本字段的键。映射中的这个键将指向我正在提取的所有字段名称的数组(用于输出)以及字符串中每个字段的长度(以便我可以解析)。

我遇到的问题是我的每个输出都将是一个包含不同字段和值的包。有些行可能有一个包含 10 个元组的包,其他行有 5 个或 6 个。我需要一种方法来在 exec 函数中定义我的模式。

编辑:

我的主要目标是能够使用我的 UDF 输入参数来使用查找图来导出我的输出模式。我将把这篇文章的其余部分留在这里作为参考,但我的主要目标是学习或找出是否可以使用输入参数然后访问映射来检索我的字段类型数组。

我试图返回一袋元组,每个元组都有一个别名或键。我有一个包含我需要用作元组别名的字符串数组的映射。根据用户对 UDF 的输入,我将获取包含我的模式的正确数组。

这在我的 exec 函数中工作正常,因为我有用户的输入。但我不知道如何将该输入也用于我的输出模式。

对于 UDF 输入,第一个参数结合第二个参数将是获取数组的键。第三个参数是一个大文本字段,我需要以特定字符间隔解析它,每个数组都不同。

public class BagTupleExampleUDF extends EvalFunc<DataBag> {

TupleFactory mTupleFactory = TupleFactory.getInstance();
BagFactory mBagFactory = BagFactory.getInstance();

/* Set up the number of fields for each loop/segment type */
HashMap<String, String[]> FieldsMap = new HashMap<String, String[]>();
Map<String,int[]> FieldsNumChar = new HashMap<String, int[]>();


@Override
public DataBag exec(Tuple tuple) throws IOException {
    setUpMaps();


    // expect one string
    if (tuple == null || tuple.size() != 3) {
        throw new IllegalArgumentException("BagTupleExampleUDF: requires 3 input parameters.");
    }
    try {

         String param1 = (String)tuple.get(0);
         String param2 = (String)tuple.get(1);
         String textArea = (String)tuple.get(2);

         String processingText = textArea;



         String paramsCombined = loop.trim()+segment.trim();
         String[] fieldsArray = loopSegmentFieldsMap.get(paramsCombined);

         int[] endFieldsIndex = loopSegmentFieldsNumChar.get(paramsCombined);
         DataBag output = mBagFactory.newDefaultBag();

         Tuple outputTuple = mTupleFactory.newTuple();
         for(int i = 0; i < fieldsArray.length; i++){

                String temp = processingText.substring(0,endFieldsIndex[i]);
                processingText = processingText.substring(endFieldsIndex[i]);
             outputTuple.append(temp);

         }




        output.add(outputTuple);


        return output;
    }
    catch (Exception e) {
        throw new IOException("BagTupleExampleUDF: caught exception processing input.", e);
    }
}

**这里我需要一些方法来根据用户的输入来访问下面的数组,以确定使用哪个模式来填写。我现在在这里硬编码垃圾。但在我的 for 循环中,我需要正确的 array.length,然后当我设置字段模式时,我将使用 array[i]

但我无法访问此函数中的数组**

public Schema outputSchema(Schema input) {
        setUpMaps();
        // Function returns a bag with this schema: { (Double), (Double) }
        // Thus the outputSchema type should be a Bag containing a Double
        try{

            Schema tupleSchema = new Schema();
            String[] test = FieldsMap.get("array1");
            for(int i = 0; i<test.length; i++){
                tupleSchema.add(new Schema.FieldSchema(test[i], DataType.CHARARRAY));

            }


            return new Schema(new Schema.FieldSchema(getSchemaName(this.getClass().getName().toLowerCase(), input), tupleSchema, DataType.BAG));
            }
        catch (Exception e){
            throw new RuntimeException(e);
        }
    }



        public void setUpMaps(){
            FieldsMap.put("array1", new String[]{"alias1","alias2","alias3","alias4","alias5","alias6","alias7","alias8","alias9"});

            FieldsNumChar.put("array1",new int[] {6,9,4,4,30,2,5,4,11});

        }
    }

实际上,我将有 10 多个数组,输入将决定我使用哪个数组和哪个模式。我已经坚持了一段时间了,无论我尝试什么,我似乎都无法得到它。

4

0 回答 0