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