递归 JSONB postgres

2024-03-25

我正在尝试在 Postgres 中构建一个支持数组和对象的递归 CTE,以返回键值对列表,但似乎无法找到一个好的示例。这是我当前的代码。

with recursive jsonRecurse as
(
select
j.key as Path
,j.key
,j.value
from jsonb_each(to_jsonb('{
    "key1": {
        "key2": [
            {
                "key3": "test3",
                "key4": "test4"
            }
        ]
    },
    "key5": [
        {
            "key6":
            [
                {
                    "key7": "test7"
                }
            ]
        }
    ]
}'::jsonb)) j

union all

select
jr.path || '.' || jr2.Key
,jr2.key
,jr2.value
from jsonRecurse jr
       left join lateral jsonb_each(jr.value) jr2 on true
where jsonb_typeof(jr.value) = 'object'
)

select
*
from jsonRecurse;

正如您所看到的,一旦我点击数组而不是对象,代码就会停止递归。我尝试使用 case 语句,并将函数调用放在 case 语句中的 jsonb_each 或 jsonb_array_element 中,但出现错误,告诉我改用横向连接。


我使用此示例表来使查询更具可读性:

create table my_table(id serial primary key, jdata jsonb);
insert into my_table (jdata) values
('{
    "key1": {
        "key2": [
            {
                "key3": "test3",
                "key4": "test4"
            }
        ]
    },
    "key5": [
        {
            "key6":
            [
                {
                    "key7": "test7"
                }
            ]
        }
    ]
}');

你必须同时加入jsonb_each(value) and jsonb_array_elements(value)有条件地,取决于类型value:

with recursive extract_all as
(
    select 
        key as path, 
        value
    from my_table
    cross join lateral jsonb_each(jdata)
union all
    select
        path || '.' || coalesce(obj_key, (arr_key- 1)::text),
        coalesce(obj_value, arr_value)
    from extract_all
    left join lateral 
        jsonb_each(case jsonb_typeof(value) when 'object' then value end) 
        as o(obj_key, obj_value) 
        on jsonb_typeof(value) = 'object'
    left join lateral 
        jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) 
        with ordinality as a(arr_value, arr_key)
        on jsonb_typeof(value) = 'array'
    where obj_key is not null or arr_key is not null
)
select *
from extract_all;

Output:

        path        |                     value                      
--------------------+------------------------------------------------
 key1               | {"key2": [{"key3": "test3", "key4": "test4"}]}
 key5               | [{"key6": [{"key7": "test7"}]}]
 key1.key2          | [{"key3": "test3", "key4": "test4"}]
 key5.0             | {"key6": [{"key7": "test7"}]}
 key1.key2.0        | {"key3": "test3", "key4": "test4"}
 key5.0.key6        | [{"key7": "test7"}]
 key1.key2.0.key3   | "test3"
 key1.key2.0.key4   | "test4"
 key5.0.key6.0      | {"key7": "test7"}
 key5.0.key6.0.key7 | "test7"
(10 rows)

json 数组的元素没有键,我们应该使用它们的索引来构建路径。因此函数jsonb_array_elements()应该按顺序调用。每文档 https://www.postgresql.org/docs/10/static/queries-table-expressions.html (see 7.2.1.4。表函数):

如果指定了WITH ORDINALITY 子句,则将向函数结果列添加一个bigint 类型的附加列。此列对函数结果集的行进行编号,从 1 开始。

函数调用

jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) 
with ordinality as a(arr_value, arr_key)

返回对(value, ordinality)别名为(arr_value, arr_key).

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

递归 JSONB postgres 的相关文章

随机推荐

  • 如何在 Jetpack Compose 中使用 Coil 制作缩写图标

    所以我使用 Coil 库进行图像处理 我注意到在占位符中它只需要一个 int 但是 如果用户没有头像或出现任何错误显示缩写 我想显示缩写 如下图所示 问题是 我是 jetpack compose 的新手 不确定如何实现这一目标 请参阅下面的
  • 当操作系统只是进程之一时,抢占式多任务处理如何工作?

    我现在正在阅读有关先发制人的多任务处理的材料 但我忘记了一件事 所有材料都暗示 操作系统以某种方式从 外部 中断了CPU上正在运行的进程 从而导致了上下文切换等 然而 我无法想象当操作系统的内核只是 CPU 上的另一个进程时 这将如何工作
  • 在 IE 中 XML 未通过响应对象正确发送到客户端

    我有一个上传控件 它从客户端调用处理程序 并将 xml 字符串发送回客户端 下面的代码在 Chrome 中工作正常 但在 IE 中将奇怪的 xml 发送回客户端 处理程序代码 public void ProcessRequest HttpC
  • 使用类似字典的结构访问 Pandas 数据框中的嵌套元素

    我有一个数据框如下 In 19 data frame Out 19 id hero 0 55c97138e5fecec26959f3b0 u info u id u 0001 u name u superman 为了过滤掉条目的名称字段 我
  • 分发 .pyc 文件有哪些限制?

    我已经开始使用 Python 开发商业应用程序 并且正在权衡如何分发该应用程序的选择 除了显而易见的 使用适当的商业许可证分发源代码 之外 我正在考虑仅分发 pyc文件没有对应的 py来源 但我对 Python 的兼容性保证还不够熟悉 不知
  • 如何设置事件的EventTarget

    如何设置事件目标 https developer mozilla org en docs Web API EventTarget一个事件的 var myObj foo bar var event new Event eventName ev
  • PEG规则识别函数原型

    我正在尝试创建一个可以解析 C 代码的解析器 我的用例是解析可能包含函数原型的缓冲区 我想将此函数名称推入符号表中 我是 Spirit 和 PEG 的新手 我正在尝试弄清楚如何编写可以识别函数原型的规则 这是我当前的实现 auto name
  • CancellationToken.ThrowIfCancellationRequested 之后出现故障与取消的任务状态

    通常我不会发布带有答案的问题 但这次我想引起一些注意 我认为这可能是一个晦涩但常见的问题 它是由这个问题 https stackoverflow com q 24346706 1768303 从那时起我回顾了自己的旧代码 发现其中一些也受到
  • UITextview打字属性不起作用

    我有 UITextView 我想将其行高设置为 50 0f 所以我使用打字属性 但没有任何效果 我的代码在 ViewDidAppear 方法中像这样 UITextView textView UITextView alloc initWith
  • java中RGB转灰度、bmp图像

    我的老师给我们布置了一个任务 要制作一个采用 640x480 bmp 彩色图像的课程 将其转换为灰度图像 我找到了一些有想法的资源 所以我做到了 但是有一个问题 因为它似乎使它不会给我错误 但输出没有出现 我认为这是我的代码 我的代码是 i
  • IntelliJ IDEA:ClassNotFoundException 如果运行调试,执行/运行确实有效

    我在 Eclipse 中启动了一个 Java Maven 项目 处理了几天 然后将其导入到 IntelliJ IDEA 中 再次处理了几天 IDEA 和 shell 中的正常运行 执行确实有效 但调试无效 当我单击调试的 Bug 图标时 它
  • Java 的反射器?

    Java 有没有相当于 NET反射器 http www red gate com products reflector 编辑 更具体地说 反编译是我所追求的 See 如何反编译Java类文件 https stackoverflow com
  • 有人将 Node.js 与 Amazon SNS 和 Apple 推送通知一起使用吗?

    我正在寻找将 node js 与 Amazon SNS 和 Apple APN 推送通知结合使用的示例 我们使用 Amazon 进行托管 我以前也使用过 SNS 这非常简单 但他们提供的推送通知示例是针对 java 的 没有针对 Node
  • Cython:(为什么/何时)使用 Py_ssize_t 进行索引是否更好?

    这是后续这个问题 https stackoverflow com questions 20978938 cython should i use np float t rather than double for typed memory v
  • 更改 UpdatePanel 外部 TextBox 中的文本

    我在 UpdatePanel 中有一个 gridview gridview 显示在弹出窗口中 单击该网格中的选择按钮后 我尝试在页面中设置文本框文本 但它不起作用 如果我删除更新面板那么它就会工作 这是我在 aspx 中的代码 div di
  • Spring security:注销后重定向到上一个网址

    我有一个使用 spring security 的网络应用程序 我想在用户注销时将用户重定向回他们注销之前所在的同一页面 是否有捷径可寻 不确定这个问题指的是哪个 Spring 版本 但有一个useReferer标准属性org springf
  • XmlWriter 编码问题

    我有以下代码 MemoryStream ms new MemoryStream XmlWriter w XmlWriter Create ms w WriteStartDocument true w WriteStartElement da
  • 如何捕获 Room 持久性库中未处理的异常

    背景 我在 Android Java 项目中使用 Room 持久性库来支持本地数据缓存 查询或保存数据时 Room 在专用线程上运行 Problem 如果 Room 管理的这些线程之一引发异常 则整个应用程序将崩溃 如果数据不一致 例如数据
  • 在 text2vec R 包中准备词嵌入

    基于text2vec包的小插图 提供了一个创建词嵌入的示例 对wiki数据进行标记 然后创建术语共现矩阵 TCM 该矩阵用于使用包中提供的glove函数创建词嵌入 我想为包中提供的电影评论数据构建词嵌入 我的问题是 我是否需要将所有电影评论
  • 递归 JSONB postgres

    我正在尝试在 Postgres 中构建一个支持数组和对象的递归 CTE 以返回键值对列表 但似乎无法找到一个好的示例 这是我当前的代码 with recursive jsonRecurse as select j key as Path j