如何在Java或Scala中读取和写入Map <string,object =“”>的镶木地板文件?

时间:2015-06-01 04:10:09

标签: java scala avro parquet

寻找一个关于如何在Java或Scala中读取和编写Runner Actor镶嵌文件的简明示例?

这是预期的结构,在Java中使用Map<String, Object>作为序列化程序(即使用镶木地板寻找等价物):

com.fasterxml.jackson.databind.ObjectMapper

3 个答案:

答案 0 :(得分:2)

我对镶木地板不太满意,但是来自here

Schema schema = new Schema.Parser().parse(Resources.getResource("map.avsc").openStream());

    File tmp = File.createTempFile(getClass().getSimpleName(), ".tmp");
    tmp.deleteOnExit();
    tmp.delete();
    Path file = new Path(tmp.getPath());

    AvroParquetWriter<GenericRecord> writer = 
        new AvroParquetWriter<GenericRecord>(file, schema);

    // Write a record with an empty map.
    ImmutableMap emptyMap = new ImmutableMap.Builder<String, Integer>().build();
    GenericData.Record record = new GenericRecordBuilder(schema)
        .set("mymap", emptyMap).build();
    writer.write(record);
    writer.close();

    AvroParquetReader<GenericRecord> reader = new AvroParquetReader<GenericRecord>(file);
    GenericRecord nextRecord = reader.read();

    assertNotNull(nextRecord);
    assertEquals(emptyMap, nextRecord.get("mymap"));

在您的情况下,使用默认地图更改ImmutableMap(Google Collections),如下所示:

Schema schema = new Schema.Parser().parse( Resources.getResource( "map.avsc" ).openStream() );

        File tmp = File.createTempFile( getClass().getSimpleName(), ".tmp" );
        tmp.deleteOnExit();
        tmp.delete();
        Path file = new Path( tmp.getPath() );

        AvroParquetWriter<GenericRecord> writer = new AvroParquetWriter<GenericRecord>( file, schema );

        // Write a record with an empty map.
        Map<String,Object> emptyMap = new HashMap<String, Object>();

        // not empty any more
        emptyMap.put( "SOMETHING", new SOMETHING() );
        GenericData.Record record = new GenericRecordBuilder( schema ).set( "mymap", emptyMap ).build();
        writer.write( record );
        writer.close();

        AvroParquetReader<GenericRecord> reader = new AvroParquetReader<GenericRecord>( file );
        GenericRecord nextRecord = reader.read();

        assertNotNull( nextRecord );
        assertEquals( emptyMap, nextRecord.get( "mymap" ) );

我没有测试代码,但试一试..

答案 1 :(得分:0)

我怀疑是否存在针对此问题的解决方案。在谈到Maps时,如果maps的值是原始类型,或者是具有原始类型字段的complexType,那么仍然可以从中创建AvroSchema。

就您而言,

  • 如果您有Map =>,它将使用以下内容创建架构 map的值是int。
  • 如果您有地图,
    • a。 CustomObject具有字段int,float,char ...(即任何原始类型)的架构 生成将是有效的,然后可以用于成功转换 拼花。
    • b。 CustomObject具有非原始字段, 生成的架构将格式错误,并且生成的ParquetWritter 将失败。

要解决此问题,您可以尝试将对象转换为JsonObject,然后使用Apache Spark库将其转换为Parquet。

答案 2 :(得分:-1)

Apache Drill是你的答案!

转换为镶木地板:您可以在钻取中使用CTAS(创建表格)功能。默认情况下,在执行以下查询后,钻取会创建一个包含镶木地板文件您可以替换任何查询并将您查询的输出写入镶木地板文件

create table file_parquet as select * from dfs.`/data/file.json`;

从镶木地板转换:我们也在这里使用CTAS功能,但是我们请求钻取使用不同的格式来编写输出

alter session set `store.format`='json';
create table file_json as select * from dfs.`/data/file.parquet`;

有关详细信息,请参阅http://drill.apache.org/docs/create-table-as-ctas-command/