将多个不同记录的阵列以Avro格式写入同一文件

时间:2018-06-20 11:41:38

标签: avro spark-avro

我们有一些旧文件格式,我需要将其迁移到Avro存储。棘手的部分是记录基本上具有

  • 一些常见字段
  • 区分项字段
  • 一些唯一字段,特定于鉴别字段选择的类型

它们全部存储在同一文件中,没有任何顺序,彼此完全混合。 (这是旧版 ...)

在Java /面向对象的编程中,可以将我们的记录概念表示如下:

abstract class RecordWithCommonFields {
   private Long commonField1;
   private String commonField2;
   ...
}

class RecordTypeA extends RecordWithCommonFields {
   private Integer specificToA1;
   private String specificToA1;
   ...
}

class RecordTypeB extends RecordWithCommonFields {
   private Boolean specificToB1;
   private String specificToB1;
   ...
}

想象一下数据是这样的:

commonField1Value;commonField2Value,TYPE_IS_A,specificToA1Value,specificToA1Value
commonField1Value;commonField2Value,TYPE_IS_B,specificToB1Value,specificToB1Value

因此,我想处理一个传入文件并将其内容写入Avro格式,以某种方式表示不同类型的记录。

有人可以给我一些实现此想法的想法吗?

1 个答案:

答案 0 :(得分:1)

Avro用户电子邮件列表中的

Nandor 足以帮助我解决this answer,这归功于他;此答案仅供参考,以防万一有人遇到相同问题。

他的解决方案很简单,通过引入一个通用的容器类和一个引用特定子类的字段,基本上使用了合成而不是继承。

通过这种方法,映射看起来像这样:

{
  "namespace": "com.foobar",
  "name": "UnionRecords",
  "type": "array",
  "items": {
    "type": "record",
    "name": "RecordWithCommonFields",
    "fields": [
      {"name": "commonField1", "type": "string"},
      {"name": "commonField2", "type": "string"},
      {"name": "subtype", "type": [
        {
          "type" : "record",
          "name": "RecordTypeA",
          "fields" : [
            {"name": "integerSpecificToA1", "type": ["null", "long"] },
            {"name": "stringSpecificToA1", "type": ["null", "string"]}
          ]
        },
        {
          "type" : "record",
          "name": "RecordTypeB",
          "fields" : [
            {"name": "booleanSpecificToB1", "type": ["null", "boolean"]},
            {"name": "stringSpecificToB1", "type": ["null", "string"]}
          ]
        }
      ]}
    ]
  }
}