递归数据类型(如 Avro 架构中的树)

2024-01-05

Reading https://avro.apache.org/docs/current/spec.html https://avro.apache.org/docs/current/spec.html它说模式必须是以下之一:

  • 一个 JSON 字符串,命名已定义的类型。
  • JSON 对象,格式为:{"type": "typeName" ...attributes...} where typeName是一个 原始或派生类型名称,如下定义。属性不 本文档中定义的内容允许作为元数据,但不得 影响序列化数据的格式。
  • 一个 JSON 数组,代表一个 嵌入式类型的联合。

我想要一个描述树的模式,使用树的递归定义:

  • 具有值(例如整数)的节点和树列表(子节点)
  • 一片有价值的叶子

我最初的尝试如下:

{
  "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 中获得我想要的东西的唯一方法还是有更好的方法?

Thanks!


虽然这不是关于表示递归命名联合的实际问题的答案(这在 2022 年末是不可能的),但可以针对树状数据结构解决这个问题。

如果你代表一个Tree作为一个节点,并且Leaf作为具有空子列表的节点,则一种递归类型就足够了:

{
  "type": "record",
  "name": "TreeNode",
  "fields": [
    {
      "name": "value",
      "type": "long"
    },
    {
      "name": "children",
      "type": { "type": "array", "items": "TreeNode" }
    }
  ]
}

现在,你的三种类型Tree, Node, and Leaf统一为一种类型TreeNode,并且没有并集Node and Leaf必要的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

递归数据类型(如 Avro 架构中的树) 的相关文章

随机推荐