阅读https://avro.apache.org/docs/current/spec.html它说模式必须是以下之一:
{"type": "typeName" ...attributes...}
其中typeName
是a
原始或派生类型名称,如下所述。属性不是
允许将本文档中定义的元数据作为元数据,但不得使用
影响序列化数据的格式。我想要一个描述树的模式,使用树的递归定义:
我最初的尝试看起来像:
{
"name": "Tree",
"type": [
{
"name": "Node",
"type": "record",
"fields": [
{
"name": "value",
"type": "long"
},
{
"name": "children",
"type": { "type": "array", "items": "Tree" }
}
]
},
{
"name": "Leaf",
"type": "record",
"fields": [
{
"name": "value",
"type": "long"
}
]
}
]
}
但Avro编译器拒绝这一点,抱怨没有类型{"name":"Tree","type":[{"name":"Node"...
。似乎Avro不喜欢顶层的联盟类型。我猜测这属于上述规则"模式必须是...... JSON对象之一..其中typeName是基本类型或派生类型名称。"我不确定"派生类型名称"虽然。起初我认为它与复杂类型相同"但这包括工会类型..
无论如何,将其更改为更复杂的定义:
{
"name": "Tree",
"type": "record",
"fields": [{
"name": "ctors",
"type": [
{
"name": "Node",
"type": "record",
"fields": [
{
"name": "value",
"type": "long"
},
{
"name": "children",
"type": { "type": "array", "items": "Tree" }
}
]
},
{
"name": "Leaf",
"type": "record",
"fields": [
{
"name": "value",
"type": "long"
}
]
}
]
}]
}
有效,但现在我有一个奇怪的记录只有一个字段,其唯一目的是让我定义我想要的顶级联合类型。
这是获得Avro我想要的唯一方法还是有更好的方式?
谢谢!
答案 0 :(得分:2)
我只是偶然发现想要定义递归联合的同一个问题。我对一个比你复杂的解决方案更清晰的解决方案感到非常悲观,因为目前没有办法命名一个联合,因此在构造它时无法以递归的方式引用它,请参阅open ticket
答案 1 :(得分:0)
如果您将Tree
表示为一个节点,而将Leaf
表示为一个具有空子列表的节点,则可以完全避免命名的并集问题,并且只需一个递归即可类型:
{
"type": "record",
"name": "TreeNode",
"fields": [
{
"name": "value",
"type": "long"
},
{
"name": "children",
"type": { "type": "array", "items": "TreeNode" }
}
]
}
现在,您的三种类型Tree
,Node
和Leaf
统一为一种类型TreeNode
,并且没有Node
和{的并集{1}}。