Java Spark二进制列拆分为多个列

Java Spark二进制列拆分为多个列,java,apache-spark,apache-spark-dataset,Java,Apache Spark,Apache Spark Dataset,我正在编写一个Java应用程序。我有一个spark数据集,它生成一个二进制类型列: Dataset<MyObject> dataset = sparkSession.createDataset(someRDD, Encoders.javaSerialization(MyObject.class)); dataset.printSchema(); //root //|-- value: binary (nullable = true) Dataset-Dataset=sparkSe

我正在编写一个Java应用程序。我有一个spark
数据集
,它生成一个二进制类型列:

Dataset<MyObject> dataset = sparkSession.createDataset(someRDD, Encoders.javaSerialization(MyObject.class));
dataset.printSchema();

//root
//|-- value: binary (nullable = true)
Dataset-Dataset=sparkSession.createDataset(someRDD,Encoders.javaSerialization(MyObject.class));
dataset.printSchema();
//根
//|--值:二进制(nullable=true)

MyObject
有不同的(嵌套的)字段,我想在数据集中的多列中“分解”它们。新列还需要从
MyObject
中的多个属性计算。作为解决方案,我可以使用
.withColumn()
并应用UDF。不幸的是,我不知道如何在UDF中接受二进制类型,然后将其转换为
MyObject
。有什么建议吗?

多亏了Blackishop的建议,我解决了这个问题。以下是完整的解决方案:

您需要注册自定义项:

UDFRegistration udfRegistration = sparkSession.sqlContext().udf();
udfRegistration.register("extractSomeLong", extractSomeLong(), DataTypes.LongType);
声明并实现UDF。第一个参数必须是byte[],您需要将byte数组转换为您的对象,如图所示:

private static UDF1<byte[], Long> extractSomeLong() {
    return (byteArray) -> {
        if (byteArray != null) {
            ByteArrayInputStream in = new ByteArrayInputStream(byteArray);
            ObjectInputStream is = new ObjectInputStream(in);
            MyObject traceWritable = (MyObject) is.readObject();
            return traceWritable.getSomeLong();
        }
        else {
            return -1L;
        }
    };
}
private static UDF1 extractSomeLong(){
返回(byteArray)->{
if(byteArray!=null){
ByteArrayInputStream in=新的ByteArrayInputStream(byteArray);
ObjectInputStream is=新的ObjectInputStream(in);
MyObject traceWritable=(MyObject)为.readObject();
返回traceWritable.getSomeLong();
}
否则{
返回-1L;
}
};
}
最后,它可以用于:

Dataset<MyObject> data = sparkSession.createDataset(someRDD, Encoders.javaSerialization(MyObject.class));
Dataset<Row> processedData = data.withColumn( "ID", functions.callUDF( "extractSomeLong", new Column("columnName")))
Dataset data=sparkSession.createDataset(someRDD,Encoders.javaSerialization(MyObject.class));
Dataset processedData=data.withColumn(“ID”,functions.callUDF(“extractSomeLong”,新列(“columnName”))

二进制表示为字节数组,您可以尝试使用
字节[]
作为UDF的输入类型。关于如何从UDF返回复杂类型,请参见本文。我认为如果需要提取多个字段,可以返回map或struct type。比使用特定的UDF提取每个UDF更好:)