5

如何从中获取JSONB紧凑PostgreSQL

获取时我得到的只是空格:

 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 ...
4

3 回答 3

7

json_strip_nulls()完全符合您的要求:

SELECT json_build_object('a', 1);

返回

{"a" : 1}

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

返回

{"a":1}

该函数不仅按照其函数名称和文档中的说明去除空值,而且顺便还去除了无关紧要的空白。后者在 PostgreSQL 手册中没有明确记录。

在 PostgreSQL 11.3 中测试,但可能也适用于早期版本。

于 2019-07-01T21:12:46.613 回答
1

jsonb在输出时以标准化格式呈现。您将不得不使用它json来保留微不足道的空白。根据文档:

因为该json类型存储输入文本的精确副本,所以它将保留标记之间的语义无关紧要的空白,以及 JSON 对象中键的顺序。此外,如果值中的 JSON 对象多次包含相同的键,则保留所有键/值对。(处理函数将最后一个值视为可操作的值。)相比之下,jsonb不保留空白,不保留对象键的顺序,并且不保留重复的对象键。

空格对于 JSON 值真的不重要。

于 2014-12-17T23:35:41.460 回答
1

有一个讨论,始于2016 年,关于jsonb_compact()解决问题的功能......但是,这可能需要数年(!)。

漂亮的解决方案

  (这个问题和另一个问题的真正解决方案)

我们必须同意 PostgreSQL 的CAST(var_jsonb AS text). 当您需要另一个强制转换约定时,例如调试或人类可读的输出,内置jsonb_pretty()函数是一个不错的选择。

不幸的是,PostgreSQL 没有提供其他选择,例如紧凑型。jsonb_pretty()因此,您可以使用一个compact选项重载:

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 文本”中删除空格——不是一项简单的任务,它需要一个好的解析器来避免篡改内容。解决方案是解析器,它不是则表达式的解决方法……而在如今,内置解析器是json_strip_nulls(),甚至作为“偶然行为”解析器。
于 2022-01-24T01:51:46.010 回答