Avro架构定义嵌套类型

Avro架构定义嵌套类型,avro,Avro,我是Avro的新手,正在浏览嵌套类型的文档。下面的示例运行良好,但是模型中的许多不同类型都有地址。是否可以定义address.avsc文件并将其引用为嵌套类型?如果可能的话,您是否可以更进一步,为客户提供一份地址列表?提前谢谢 {"namespace": "com.company.model", "type": "record", "name": "Customer", "fields": [ {"name": "firstname", "type": "string"},

我是Avro的新手,正在浏览嵌套类型的文档。下面的示例运行良好,但是模型中的许多不同类型都有地址。是否可以定义address.avsc文件并将其引用为嵌套类型?如果可能的话,您是否可以更进一步,为客户提供一份地址列表?提前谢谢

{"namespace": "com.company.model",
  "type": "record",
  "name": "Customer",
  "fields": [
    {"name": "firstname", "type": "string"},
    {"name": "lastname", "type": "string"},
    {"name": "email", "type": "string"},
    {"name": "phone", "type": "string"},
    {"name": "address", "type":
      {"type": "record",
       "name": "AddressRecord",
       "fields": [
         {"name": "streetaddress", "type": "string"},
         {"name": "city", "type": "string"},
         {"name": "state", "type": "string"},
         {"name": "zip", "type": "string"}
       ]}
    }
  ]
}

有4种可能的方法:

  • 如本文所述,将其包含在pom文件中。
  • 在单个avsc文件中声明所有类型。
  • 使用一个静态解析器,首先解析所有导入,然后解析实际数据类型。
  • (这是一个黑客)使用avdl文件,并使用类似的导入。不过,IDL是用于RPC调用的。
  • 2的示例。在一个avsc文件中声明所有类型。还回答了地址上的数组声明

    [
    {
        "type": "record",
        "namespace": "com.company.model",
        "name": "AddressRecord",
        "fields": [
            {
                "name": "streetaddress",
                "type": "string"
            },
            {
                "name": "city",
                "type": "string"
            },
            {
                "name": "state",
                "type": "string"
            },
            {
                "name": "zip",
                "type": "string"
            }
        ]
    },
    {
        "namespace": "com.company.model",
        "type": "record",
        "name": "Customer",
        "fields": [
            {
                "name": "firstname",
                "type": "string"
            },
            {
                "name": "lastname",
                "type": "string"
            },
            {
                "name": "email",
                "type": "string"
            },
            {
                "name": "phone",
                "type": "string"
            },
            {
                "name": "address",
                "type": {
                    "type": "array",
                    "items": "com.company.model.AddressRecord"
                }
            }
        ]
    },
    {
        "namespace": "com.company.model",
        "type": "record",
        "name": "Customer2",
        "fields": [
            {
                "name": "x",
                "type": "string"
            },
            {
                "name": "y",
                "type": "string"
            },
            {
                "name": "address",
                "type": {
                    "type": "array",
                    "items": "com.company.model.AddressRecord"
                }
            }
        ]
    }
    ]
    
    3的示例。使用单个静态解析器

    Parser parser = new Parser(); // Make this static and reuse
    parser.parse(<location of address.avsc file>);
    parser.parse(<location of customer.avsc file>);
    parser.parse(<location of customer2.avsc file>);
    
    Parser Parser=new Parser();//将此设置为静态并重用
    parser.parse();
    parser.parse();
    parser.parse();
    
    如果我们想要保留模式,也就是说如果我们想要创建新记录,我们可以 方法来获取架构 或

    Parser Parser=new Parser();//将此设置为静态并重用
    Schema addressSchema=parser.parse();
    模式customerSchema=parser.parse();
    Schema customer2Schema=parser.parse();
    
    要添加到@Princey James answer,必须先定义嵌套类型,然后才能使用。

    其他添加到@Princey James answer

    使用2的示例。在单个avsc文件中声明所有类型。

    Parser parser = new Parser(); // Make this static and reuse
    parser.parse(<location of address.avsc file>);
    parser.parse(<location of customer.avsc file>);
    parser.parse(<location of customer2.avsc file>);
    
    它将用于序列化和反序列化,并生成代码

    但是在不生成代码的情况下序列化和反序列化不起作用

    您将获得org.apache.avro.AvroRuntimeException:非记录模式:[{“类型”:

    代码生成的工作示例:

    @测试
    public void avroWithCode()引发IOException{
    UserPerso UserPerso3=UserPerso.newBuilder()
    .setName(“查理”)
    .setFavoriteColor(“蓝色”)
    .setFavoriteNumber(空)
    .build();
    AddressRecord Address=AddressRecord.newBuilder()
    .setStreetaddress(“mo”)
    .setCity(“巴黎”)
    .setState(“IDF”)
    .setZip(“75”)
    .build();
    ArrayList li=新的ArrayList();
    加上(地址);
    Customer cust=Customer.newBuilder()
    .setUser(UserPerso3)
    .setPhone(“0101010101”)
    .setAddress(li)
    .build();
    字符串fileName=“cust.avro”;
    文件a=新文件(文件名);
    DatumWriter customerDatumWriter=新的指定DatumWriter(Customer.class);
    DataFileWriter DataFileWriter=新的DataFileWriter(customerDatumWriter);
    创建(cust.getSchema(),新文件(fileName));
    dataFileWriter.append(cust);
    dataFileWriter.close();
    DatumReader custDatumReader=新的SpecificDatumReader(Customer.class);
    DataFileReader DataFileReader=新的DataFileReader(a,custDatumReader);
    Customer cust2=null;
    while(dataFileReader.hasNext()){
    cust2=dataFileReader.next(cust2);
    系统输出打印项次(cust2);
    }
    }
    
    没有:

    @测试
    public void avroWithoutCode()引发IOException{
    Schema schemaUserso=new Schema.Parser().parse(新文件(“src/main/resources/avroTest/user.avsc”);
    Schema schemaAddress=new Schema.Parser().parse(新文件(“src/main/resources/avroTest/user.avsc”);
    Schema schemaCustomer=new Schema.Parser().parse(新文件(“src/main/resources/avroTest/user.avsc”);
    System.out.println(schemaUserso);
    GenericRecordUserPerso3=新的GenericData.Record(schemaUserPerso);
    用户perso3.put(“姓名”、“查理”);
    用户perso3.put(“最喜欢的颜色”、“蓝色”);
    UserPerso3.put(“最喜欢的号码”,null);
    GenericRecord地址=新的GenericData.Record(SchemaAddress);
    地址put(“街道地址”、“mo”);
    地址:put(“城市”、“巴黎”);
    地址:put(“州”、“IDF”);
    地址:邮政编码(“zip”,“75”);
    ArrayList li=新的ArrayList();
    加上(地址);
    GenericRecord cust=新的GenericData.Record(schemaCustomer);
    客户投入(“用户”,UserPerso3);
    客户投入(“电话”、“0101010101”);
    客户投入(“地址”,li);
    字符串fileName=“cust.avro”;
    文件=新文件(文件名);
    DatumWriter DatumWriter=新的通用DatumWriter(schemaCustomer);
    DataFileWriter DataFileWriter=新的DataFileWriter(datumWriter);
    创建(schemaCustomer,文件);
    dataFileWriter.append(cust);
    dataFileWriter.close();
    文件a=新文件(文件名);
    DatumReader DatumReader=新的通用DatumReader(schemaCustomer);
    DataFileReader DataFileReader=新的DataFileReader(a,datumReader);
    GenericRecord cust2=null;
    while(dataFileReader.hasNext()){
    cust2=dataFileReader.next(cust2);
    系统输出打印项次(cust2);
    }
    }
    
    不清楚如何使用示例3中的解析器。创建解析器后,如何创建记录(空白记录,而不是反序列化)@RedBullet我编辑了我的答案来澄清你的疑问。希望现在清楚了。在#2中,你的根类型是一个并集,对吗?这样用户就可以将这些顶级类型中的任何一个序列化为根对象?这有点不幸,因为如果你只想在顶级序列化客户对象,你就无法真正让它以这种方式工作.我正在尝试选项2-但是当我使用它时,我得到一个错误-您能确认它应该是
    {“name”:“address”,“type”:“com.company.model.AddressR”吗