2016-04-25 103 views
0

如何從java中的avro-parquet文件讀取字段子集?如何從Java中的Avro-Parquet文件讀取特定字段?

我想我可以定義一個avro模式,它是存儲的記錄的一個子集,然後讀取它們...但我得到一個異常。

這裏是我試圖解決它

我有2種Avro的模式:

  • CLASSA
  • ClassB的

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())得到了ClassCastExceptionCannot convert ClassA to ClassB

我想讀者從文件讀取的模式。

我試圖發送模型(即builder.withModel)但自classB extends org.apache.avro.specific.SpecificRecordBase它引發異常。

我事件試圖設置架構的配置和設置它通過builder.withConfig但沒有雪茄......

回答

1

所以......

幾件事情:

  • 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的實木複合地板的文件,有一個簡便方法 - 這裏是一個火花的例子:

 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); 
相關問題