在PostgreSQL中提取JSONB的压缩版本

nom7f22z  于 2023-01-25  发布在  PostgreSQL
关注(0)|答案(3)|浏览(146)

如何从PostgreSQL中提取压缩的JSONB
我在取数时得到的都是空格:

SELECT data FROM a_table WHERE id = 1; -- data is JSONB column

 {"unique": "bla bla", "foo": {"bar": {"in ...
^          ^          ^      ^       ^ --> spaces

我想要的是:

{"unique":"bla bla","foo":{"bar":{"in ...
qni6mghb

qni6mghb1#

json_strip_nulls()完全可以满足您的需求:

SELECT json_build_object('a', 1);

退货

{"a" : 1}

但是

SELECT json_strip_nulls(json_build_object('a', 1));

退货

{"a":1}

这个函数不仅可以去除函数名中的空值和documented,还可以去除不重要的空格,后者在PostgreSQL手册中没有明确的说明。
在PostgreSQL 11.3中测试,但可能也适用于早期版本。

cu6pst1q

cu6pst1q2#

jsonb在输出时以标准格式呈现。您必须改用json来保留不重要白色。Per documentation:
因为json类型存储了输入文本的精确副本,所以它将保留标记之间语义上无关紧要白色,以及JSON对象中键的顺序,而且,如果值中的JSON对象多次包含相同的键,则所有键/值对都将保留。(处理函数将最后一个值视为操作值。)相比之下,jsonb不保留白色,不保留对象键的顺序,并且不保留重复的对象键。
空格对于JSON值来说并不重要。

waxmsbnn

waxmsbnn3#

有一个discussion, started in 2016, about a function jsonb_compact()可以解决这个问题...但是,这可能需要几年的时间(!)。

漂亮的解决方案

(这个问题和this other one的真实的解决方案)
我们必须同意PostgreSQL的CAST(var_jsonb AS text)转换约定。当你需要另一个转换约定时,例如调试或人类可读的输出,内置的jsonb_pretty()函数是一个很好的选择。
不幸的是,PostgreSQL没有提供其他选项,比如compact选项。因此,您可以使用compact选项重载jsonb_pretty()

CREATE or replace FUNCTION jsonb_pretty(
  jsonb,            -- input
  compact boolean   -- true for compact format
) RETURNS text AS $$
  SELECT CASE
    WHEN $2=true THEN json_strip_nulls($1::json)::text
    ELSE  jsonb_pretty($1)
  END
$$ LANGUAGE SQL IMMUTABLE;

SELECT jsonb_pretty(  jsonb_build_object('a',1, 'bla','bla bla'), true );
-- results  {"a":1,"bla":"bla bla"}

依据

  • JSON标准RFC 8259规定 "......在六个结构字符中的任何一个之前或之后都允许不重要的空格”。换句话说,从jsonb数据类型到text的转换没有规范形式。PostgreSQL转换约定(使用空格)是任意的
    *许多应用程序需要最小化大的JSONb输出。将大JSONb的文件大小最小化,节省pg_file_write();在REST接口中在线输出。
  • PostgreSQL团队必须欣赏真实的的CAST过程,而不是解析器,而是从JSONb内部表示直接生成的文本。
  • 解决方案-删除“JSON文本”中的空格-不是一个简单的任务,它需要一个好的解析器来避免篡改内容。解决方案是一个解析器,它不是regular expression workaround...而且现在内置的解析器是json_strip_nulls(),甚至是“偶然行为”解析器。

相关问题