1

我们有一些旧文件格式,我需要将其迁移到 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 格式,以某种方式表示不同类型的记录。

有人可以给我一些关于如何实现这一目标的想法吗?

4

1 回答 1

1

Avro 用户电子邮件列表中的Nandor非常友好地帮助我解决了这个问题,感谢他;这个答案是记录在案的,以防其他人遇到同样的问题。

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

使用这种方法,映射如下所示:

{
  "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"]}
          ]
        }
      ]}
    ]
  }
} 
于 2018-07-04T15:59:28.877 回答