编辑:我将尝试解释一下我想做什么。
1行输入如下:field1,field2,textfield
现在 textfield 是一个固定字符数的字符串条目。我想解析这个字符串以从这些字符中提取子字符串。因此,例如,我想提取前10个字符并将其作为一个字段,提取下一个15并将其作为字段等...
那部分没问题。问题不是每行都有相同的文本字段规则。基本上 field1 和 field2 将代表我用来解析该文本字段的关键。映射中的这个键将指向我正在提取的所有字段名称的数组(在输出中使用)以及字符串中每个字段的长度(以便我可以解析)。
我遇到的问题是我的每个输出都是一个包含不同字段和值的包。有些行可能有一个包含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,然后当我设置字段模式时,我将使用数组[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多个数组,输入将决定我使用哪个数组和哪个模式。我已经坚持了一段时间了,无论我尝试什么,我似乎无法得到它。