如何从java中的avro parquet文件中读取特定字段?

wvyml7n5  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(398)

如何从java中的avro parquet文件中读取字段子集?
我想我可以定义一个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);
        }

但我得到一个 ClassCastException 在线 (record=reader.read()) : Cannot convert ClassA to ClassB 我想读者正在从文件中读取模式。
我试着把模型送进来。 builder.withModel )但是自从B级 extends org.apache.avro.specific.SpecificRecordBase 它抛出了一个异常。
我尝试在配置中设置模式并将其设置为通过 builder.withConfig 但是没有雪茄。。。

pftdvrlh

pftdvrlh1#

所以。。。
两件事: 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);
}

另外,如果您计划使用inputformat来读取avro parquet文件,有一个方便的方法-下面是一个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);

相关问题