从存储在 postgresql 数据库中的 JSON 中选择文本或数字时遇到问题

Posted

技术标签:

【中文标题】从存储在 postgresql 数据库中的 JSON 中选择文本或数字时遇到问题【英文标题】:Trouble selecting text or numbers from a JSON stored in a postgresql DB 【发布时间】:2021-01-20 21:57:33 【问题描述】:

这是我之前提出的这个问题的后续:Querying an array of objects in JSONB

我有一个表,其中有一列数据类型为 JSONB。列中的每一行都有一个如下所示的 JSON:

[
   "A": "AA": "something", "AB": false,
   "B": "BA":["BAAA": [1,2,3,4],"BABA": "one": 42]
]

注意:JSON 是一堆乱七八糟的列表和对象,总共有 300 行。不是我的数据,但我坚持下去。 :(

我使用的是 postgresql 版本 12

我正在尝试编写一个查询来返回 AA (A->AA) 的值。这是我尝试过的查询:

select data @@ '$[*].A.AA' from test

那只是返回 null。

但是当我运行这个查询时:

select data @@ '$[*].A.AB' from test

它正确返回 false。

问题:

为什么查询返回类型为布尔值时返回值,返回类型为文本时返回null? 如何编写查询以返回文本?

一些示例数据:https://dbfiddle.uk/?rdbms=postgres_12&fiddle=fec0ba6e9bd6dffb9874e20ef7abab1d

【问题讨论】:

运算符 @@ 返回一个布尔值 - 它测试 JSONPath 表达式是否存在。它不会返回该路径的值。它类似于常规 SQL 中的 EXISTS 条件 【参考方案1】:

您误解了@@ 的作用。它检查 JSONPath 表达式是否为真。它不会返回该路径的值。

'$[*].A.AB' 这样的路径表达式对于@@ 运算符实际上没有意义,因为它不包含任何可以计算的条件运算符,如==<>

'$[*].A.AB' 恰好可以工作,因为该路径的值是布尔值。如果那是例如一个整数,它也会return null

如果要通过JSON路径函数取值,需要使用jsonb_path_query_first()

select jsonb_path_query_first(data, '$[*].A.AB') 
from test

请注意,结果仍然是 JSONB 值,而不是 text 值。如果您希望它为text,请使用jsonb_path_query_first(data, '$[*].A.AB') #>> '

dbFiddle


如果有像#> 这样的运算符接受JSONPath 来提取该路径的值,那确实很好,但目前我们不得不忍受笨拙的jsonb_path_query_first()

【讨论】:

以上是关于从存储在 postgresql 数据库中的 JSON 中选择文本或数字时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

将数据从Json文件加载到Postgresql会导致:错误“重复键值违反唯一约束 - 已存在”。

在 postgresql 的 jsonb[] 类型列中插入数据的正确语法是啥

从 ExtJS 4 中的存储重新加载数据

在不使用 S3 存储桶的情况下将数据从远程服务器的 .gz 文件加载到 redshift 的 postgresql 实例?

错误:Postgresql 中的日期/时间字段值超出范围

将 json 对象存储到 postgresql 中的数据类型是啥?