Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用不同的字段名在Java类上映射Avro文件_Java_Apache Spark_Spark Dataframe_Spark Avro - Fatal编程技术网

使用不同的字段名在Java类上映射Avro文件

使用不同的字段名在Java类上映射Avro文件,java,apache-spark,spark-dataframe,spark-avro,Java,Apache Spark,Spark Dataframe,Spark Avro,我有一个简单的spark任务的问题,它读取Avro文件,然后将其保存为蜂巢拼花表 我有两种类型的文件,通常它们是相同的,但是密钥结构有点不同-字段名 类型1 root |-- pk: strucnt (nullable = true) |-- term_id: string (nullale = true) 类型2 root |-- pk: strucnt (nullable = true) |-- id: string (nullale = true) 我正在用spark

我有一个简单的spark任务的问题,它读取Avro文件,然后将其保存为蜂巢拼花表

我有两种类型的文件,通常它们是相同的,但是密钥结构有点不同-字段名

类型1

root
|-- pk: strucnt (nullable = true)
    |-- term_id: string (nullale = true)
类型2

root
|-- pk: strucnt (nullable = true)
    |-- id: string (nullale = true)
我正在用spark Avro阅读Avro。然后像这样把这个DF映射到bean

Dataset<SomeClass> df = avroDF.as(Encoders.bean(SomeClass.class));
所以,如果我读的是Avro 1型-没关系。但是,如果我正在读取Avro类型2,则会发生错误。反之亦然,如果我将字段名更改为
私有字符串id

我的问题有没有普遍的解决办法?我找到了@AvroName,但它不允许设置多个名称。
谢谢。

唯一的方法是将数据集字段名更改为架构中的名称。 使用此示例执行此操作:

val newName = Seq("id", "x1", "x2", "x3")
Dataset<SomeClass> df = avroDF.toDF(newNames: _*).as(Encoders.bean(SomeClass.class));
val newName=Seq(“id”、“x1”、“x2”、“x3”)
数据集df=avroDF.toDF(新名称:*).as(Encoders.bean(SomeClass.class));

您不能将dataframe强制转换为具有不同字段名的BeanClass。

可能的解决方案是

StructType avroExtendedSchema = avroDF.schema().add("id",DataTypes.StringType);
avroDF.map(row->RowFactory(row.getStruct(0),row.getStruct(0).getString(0)), 
       RowEncoder.apply(avroExtendedSchema)).toDF();
因此,DF的第二个字段将命名为“id”,并包含字符串键。将来可以删除第一个“pk”结构

avroDF.drop("pk");
PS 我发现了第三种模式:

root
|-- pk: strucnt (nullable = true)
    |-- id: int(nullale = true)
最后的代码是这样的:

DataType keyType = avroDF.select("pk.*").schema().fields[0].dataType();
StructType avroExtendedSchema = avroDF.schema().add("id",keyType);
avroDF.map(row->RowFactory(row.getStruct(0),row.getStruct(0).get(0)), 
       RowEncoder.apply(avroExtendedSchema)).drop("pk").toDF();
此代码适用于任何基元\字符串键

DataType keyType = avroDF.select("pk.*").schema().fields[0].dataType();
StructType avroExtendedSchema = avroDF.schema().add("id",keyType);
avroDF.map(row->RowFactory(row.getStruct(0),row.getStruct(0).get(0)), 
       RowEncoder.apply(avroExtendedSchema)).drop("pk").toDF();