当前位置: 首页 > 知识库问答 >
问题:

像树一样的递归数据类型作为Avro模式

沈树
2023-03-14

阅读 https://avro.apache.org/docs/current/spec.html 它说架构必须是以下之一:

  • 一个JSON字符串,用于命名定义的类型
  • 一个JSON对象,其形式为:{“type”:“typeName”…attributes…},其中typeName是原始类型名或派生类型名,定义如下。允许将本文档中未定义的属性作为元数据,但不得影响序列化数据的格式
  • 一个JSON数组,表示嵌入类型的联合

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

    < li >具有一个值(比如整数)和一个树列表(子树)的节点 < li >一片有价值的树叶

我最初的尝试看起来像:

{
  "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编译器拒绝了这一点,抱怨没有类型< code>{"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获得我想要的东西的唯一方法还是有更好的方法?

谢谢

共有2个答案

上官培
2023-03-14

我只是偶然发现了同样的问题,想定义一个递归联合。我对一个比你复杂的解决方案更干净的解决方案很悲观,因为目前没有办法命名一个联合,因此在构造它的时候也没有办法递归地引用它

姬天宇
2023-03-14

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

如果将表示为节点,将 Leaf 表示为具有空子级列表的节点,则一个递归类型就足够了:

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

现在,您的三种类型< code>Tree 、< code>Node和< code>Leaf统一为一种类型< code>TreeNode,并且不需要< code>Node和< code>Leaf的联合。

 类似资料:
  • 我从本例中的createDataFrame调用中获得了一个StackOverflow Error。它起源于涉及java类型推理的scala代码,该代码在无限循环中调用自己。 堆栈跟踪的底部如下所示: 这与中报告的错误类似http://apache-spark-developers-list.1001551.n3.nabble.com/Stackoverflow-in-createDataFrame

  • 标准 ML 没有多态递归。在模块语言中添加递归允许我们使用内函子的固定点将多态递归恢复为一种特殊情况。例如: 众所周知,多态递归使得类型推理不可判定。然而,函子定义已经包含部分类型信息,即其参数的签名。这些信息足以使类型推理再次可判定吗?

  • 本文向大家介绍数据结构 二叉树的递归与非递归,包括了数据结构 二叉树的递归与非递归的使用技巧和注意事项,需要的朋友参考一下 数据结构 二叉树的递归与非递归 实例代码:  先序遍历(递归法)   后序遍历      感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • 问题内容: 我是mysql的新手。这是我的桌子: 类别表: 每个类别都有一个父项,我想准备它们以显示在下拉菜单中。 这就是我想要得到的: 在这里,类别没有顺序,我的代码必须为远离父母的孩子类别提供顺序。根据每个类别的父母的深度提供姓名前的缩进。每个类别的孩子数没有限制,但是类别总数不超过100。 有没有查询可以给出这样的结果?我更喜欢可以在PHP框架中以活动记录形式运行的查询。 问题答案: 这个

  • 我试图在Python中做一个函数,它接受树的任意节点,并根据节点给出的列表填充列表。 考虑到以下绘制糟糕的树: 例如,如果我们从节点5开始,我们应该得到: 包含具有相同父节点的所有节点的列表,包括我们从(4和5)开始的节点。 任何子节点,但不是其子节点(6) 父节点和具有相同父节点的任何父节点,以及它们的父节点,等等,直到我们到达根节点,但不包括根节点(在本例中只有2和3个,但如果树更深,我们开始

  • 我一直在做一个项目,在汇编中写一个递归函数,在那里它将计算斐波那契数。一开始我用Java代码写的: 这个递归函数工作得非常好。虽然当尝试在汇编代码中实现它时,我没有得到我所期望的结果。在排除了一段时间的故障后,我在Java编写了大致等价的代码: 这个函数得到了和我在汇编代码中得到的一样错误的结果,虽然我仍然不明白为什么,我遗漏了什么?这两个函数重复的次数相同。 结果 ASMFibonacci 0