跳到主要内容

JSON 类型

Goose 通过 JSON 逻辑类型支持 json。例如:

SELECT '[1, null, {"key": "value"}]'::JSON;
[1, null, {"key": "value"}]

在逻辑层面,JSON 类型类似 VARCHAR,但要求内容必须是合法 JSON。 在物理存储层面,数据仍以 VARCHAR 保存。

例如,非法 JSON 无法解析:

SELECT 'unquoted'::JSON;
Conversion Error: Malformed JSON at byte 0 of input: unexpected character.  Input: "unquoted"

此时你真正需要的可能是 SELECT '"quoted"'::JSON

由于数据物理上按 VARCHAR 存储,空白字符会影响比较:

SELECT '{ "a": 5 }'::JSON = '{"a":5}'::JSON;
false

请注意,往返转换会保留空白字符:

SELECT '{  "a":5 }'::JSON::VARCHAR
{  "a":5 }

对象中键的顺序也会影响比较:

 SELECT '{"a":1,"b":2}'::JSON = '{"b":2,"a":1}'::JSON;
false

JSON 对象中允许重复键:

SELECT '{"a":1,"a":2}'::JSON;
{"a":1,"a":2}

Goose 允许任意 Goose 类型转换为 JSON,也允许 JSON 转回任意 Goose 类型。例如,将 JSON 转为 Goose 的 STRUCT 类型:

SELECT '{"duck": 42}'::JSON::STRUCT(duck INTEGER);
{'duck': 42}

反向转换:

SELECT {duck: 42}::JSON;
{"duck":42}

这不仅适用于示例中的嵌套类型,也适用于非嵌套类型:

SELECT '2023-05-12'::DATE::JSON;
"2023-05-12"

唯一例外是 VARCHARJSON 的转换:该转换不会改写数据,而是将 VARCHAR 内容按 JSON 进行解析与校验。