Hadoop 如何从Java中的Avro拼花文件中读取特定字段?

Hadoop 如何从Java中的Avro拼花文件中读取特定字段?,hadoop,apache-spark,avro,parquet,Hadoop,Apache Spark,Avro,Parquet,如何从java中的avro拼花文件中读取字段子集 我想我可以定义一个avro模式,它是存储记录的子集,然后读取它们……但我得到了一个例外 以下是我试图解决这个问题的方法 我有两个avro模式: 甲级 B类 ClassB的字段是ClassA的子集 final Builder<ClassB> builder = AvroParquetReader.builder(files[0].getPath()); final ParquetReader<C

如何从java中的avro拼花文件中读取字段子集

我想我可以定义一个avro模式,它是存储记录的子集,然后读取它们……但我得到了一个例外

以下是我试图解决这个问题的方法

我有两个avro模式:

  • 甲级
  • B类
ClassB的字段是ClassA的子集

        final Builder<ClassB> builder = AvroParquetReader.builder(files[0].getPath());
        final ParquetReader<ClassB> reader = builder.build();
        //AvroParquetReader<ClassA> readerA = new AvroParquetReader<ClassA>(files[0].getPath());
        ClassB record = null;
        final List<ClassB> list = new ArrayList<>();
        while ((record = reader.read()) != null) {
            list.add(record);
        }
final Builder=AvroParquetReader.Builder(文件[0].getPath());
最终拼花板阅读器=builder.build();
//AvroParquetReader readerA=新的AvroParquetReader(文件[0].getPath());
ClassB记录=null;
最终列表=新的ArrayList();
while((record=reader.read())!=null){
列表。添加(记录);
}
但是我在
(record=reader.read())
上得到一个
ClassCastException
无法将ClassA转换为ClassB

我想读者正在从文件中读取模式

我试图发送模型(即
builder.withModel
),但由于classB
扩展了org.apache.avro.specific.SpecificRecordBase
,它抛出了一个异常

我尝试在配置中设置架构,并通过
builder.withConfig
进行设置,但没有雪茄…

所以

两件事:

  • AvroReadSupport.setRequestedProjection(hadoopConf,ClassB.$Schema)
    可用于为所选列设置投影
  • reader.readNext
    方法仍将返回
    ClassA
    对象,但将清空
    ClassB
    中不存在的字段
要直接使用读卡器,您可以执行以下操作:

AvroReadSupport.setRequestedProjection(hadoopConf, ClassB.SCHEMA$);
final Builder<ClassB> builder = AvroParquetReader.builder(files[0].getPath());
final ParquetReader<ClassA> reader = builder.withConf(hadoopConf).build();

ClassA record = null;
final List<ClassA> list = new ArrayList<>();
while ((record = reader.read()) != null) {
    list.add(record);
}
AvroReadSupport.setRequestedProjection(hadoopConf,ClassB.SCHEMA$);
final Builder=AvroParquetReader.Builder(文件[0].getPath());
最终ParquetReader reader=builder.withConf(hadoopConf.build();
ClassA记录=null;
最终列表=新的ArrayList();
while((record=reader.read())!=null){
列表。添加(记录);
}
此外,如果您计划使用inputformat读取avro拼花地板文件,还有一种方便的方法-下面是一个spark示例:

        final Job job = Job.getInstance(hadoopConf);
        ParquetInputFormat.setInputPaths(job, pathGlob);
        AvroParquetInputFormat.setRequestedProjection(job, ClassB.SCHEMA$);

        @SuppressWarnings("unchecked")
        final JavaPairRDD<Void, ClassA> rdd = sc.newAPIHadoopRDD(job.getConfiguration(), AvroParquetInputFormat.class,
                Void.class, ClassA.class);
final Job Job=Job.getInstance(hadoopConf);
ParquetInputFormat.setInputPaths(作业,路径glob);
AvroParquetInputFormat.setRequestedProjection(作业,ClassB.SCHEMA$);
@抑制警告(“未选中”)
final javapairdd rdd=sc.newAPIHadoopRDD(job.getConfiguration(),AvroParquetInputFormat.class,
空类,类A类);