如何从 Java 中的 Avro-Parquet 文件中读取特定字段?
How to read specific fields from Avro-Parquet file in Java?
如何从 java 中的 avro-parquet 文件读取部分字段?
我想我可以定义一个 avro 模式,它是存储记录的一个子集,然后读取它们...但是我得到一个异常。
这是我尝试解决的方法
我有 2 个 avro 模式:
- A 类
- 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);
}
但是我在 (record=reader.read())
线上收到 ClassCastException
:Cannot convert ClassA to ClassB
我想 reader 正在从文件中读取模式。
我尝试发送模型(即 builder.withModel
),但由于 classB extends org.apache.avro.specific.SpecificRecordBase
它抛出异常。
我尝试在配置中设置架构并通过 builder.withConfig
设置它,但没有雪茄...
所以...
两件事:
AvroReadSupport.setRequestedProjection(hadoopConf, ClassB.$Schema)
可用于为所选列设置投影。
reader.readNext
方法仍然会 return 一个 ClassA
对象,但会清除 ClassB
. 中不存在的字段
要直接使用 reader,您可以执行以下操作:
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);
}
此外,如果您打算使用输入格式来读取 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);
如何从 java 中的 avro-parquet 文件读取部分字段?
我想我可以定义一个 avro 模式,它是存储记录的一个子集,然后读取它们...但是我得到一个异常。
这是我尝试解决的方法
我有 2 个 avro 模式:
- A 类
- 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);
}
但是我在 (record=reader.read())
线上收到 ClassCastException
:Cannot convert ClassA to ClassB
我想 reader 正在从文件中读取模式。
我尝试发送模型(即 builder.withModel
),但由于 classB extends org.apache.avro.specific.SpecificRecordBase
它抛出异常。
我尝试在配置中设置架构并通过 builder.withConfig
设置它,但没有雪茄...
所以...
两件事:
AvroReadSupport.setRequestedProjection(hadoopConf, ClassB.$Schema)
可用于为所选列设置投影。reader.readNext
方法仍然会 return 一个ClassA
对象,但会清除ClassB
. 中不存在的字段
要直接使用 reader,您可以执行以下操作:
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);
}
此外,如果您打算使用输入格式来读取 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);