【问题标题】:Alternative ways to extract the contents of a JSON string提取 JSON 字符串内容的替代方法
【发布时间】:2021-09-06 13:34:56
【问题描述】:

考虑以下查询:

select '"{\"foo\":\"bar\"}"'::json;

这将返回包含 JSON string 的单个元素的单个记录。见:

test=# select json_typeof('"{\"foo\":\"bar\"}"'::json);                                                                                                                                                                                                                                                                                                                                                                                   json_typeof 
-------------
 string
(1 row)

可以如下提取字符串的内容:

=# select ('"{\"foo\":\"bar\"}"'::json) #>>'{}';
     json      
---------------
 {"foo":"bar"}
(1 row)

从现在开始,结果可以转换为 JSON object

test=# select json_typeof((('"{\"foo\":\"bar\"}"'::json) #>>'{}')::json);
 json_typeof 
-------------
 object
(1 row)

这种方式看起来很神奇。

我在提取运算符中没有定义路径,但返回的不是我传递的。这似乎没有将索引传递给数组访问器,并返回一个元素。

我担心我会混淆下一个维护者来查看这个逻辑。

有没有更神奇的方法来做到这一点?

【问题讨论】:

  • 我不知道你在问什么。是不是您有一列 json 类型的列,并且您希望它呈现为文本,例如 {"foo":"bar"}
  • @Bohemian 我试图尽可能地简化它。这里的实际用例是我有一个 json 列错误地包含 json strings 包含引用的 json 对象,而不是 just json 对象。我上面的例子也是一样的:一个json字符串封装的json对象。我可以使用上面的运算符进行提取,但我可以看到它真的很混乱。这不是一个“我被困”的问题,而是一个“帮助我找到更好的方法”的问题。
  • 另外,这可能是 postgres 邮件列表的问题。我可以把它漂浮在那里。
  • 为什么不存储'{"foo":"bar"}' 直接将 JSON 键/值对存储为转义的 JSON 字符串并没有什么意义。

标签: json postgresql


【解决方案1】:

但是您确实定义了一条路径。将“root”定义为路径只是另一条路径。这正是#>> operator 的用途:

将指定路径的 JSON 子对象提取为text

呈现为text 有效地应用字符串中的转义字符。当回溯到json 时,双引号(不再转义)的特殊含义开始发挥作用。没有什么神奇的。没有比这更好的方法了。

如果您希望它对来世感到困惑,请添加 cmets 来解释您在那里所做的事情。

也许,为了清楚起见,您可以改用等效函数json_extract_path_text()The manual:

将指定路径处的 JSON 子对象提取为文本。 (这在功能上等同于 #>> 运算符。)

现在,该函数有一个VARIADIC 参数,您通常会一个接一个地输入路径元素,如手册中的示例所示:

json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}',
'f4', 'f6') → foo

您不能以这种方式输入“根”路径。但是(此时手册未添加的内容)您也可以在添加关键字VARIADIC 后提供一个实际数组。见:

这样就可以了:

SELECT json_extract_path_text('"{\"foo\":\"bar\"}"'::json, VARIADIC '{}')::json;

既然我们都是为了显式,请使用详细的 SQL 标准强制转换语法:

SELECT cast(json_extract_path_text('"{\"foo\":\"bar\"}"'::json, VARIADIC '{}') AS json)

还有更清楚的吗? (我个人更喜欢你较短的原版,但我可能有偏见,因为我是 Postgres 的“母语人士”..)

问题是,为什么一开始就有包含转义为 JSON 字符串的奇怪 JSON 文字?

【讨论】:

  • “(问题是,为什么你有那个奇怪的 JSON 文字,包括作为 JSON 字符串的转义?)”这是应用程序代码中错误地写成文本的数据。 :grimacing: 我写的查询是为了清理数据。
  • @EdCarrel:我明白了。那么剩下的问题是:这个问题的回答正确吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多