9.15. JSON 函数和操作符

Table 9-40展示了可以用于两种 JSON 数据类型(见Section 8.14)的操作符。

Table 9-40. jsonjsonb 操作符

操作符右操作数类型描述例子例子结果
->int获得 JSON 数组元素(索引从 0 开始)'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2{"c":"baz"}
->text通过键获得 JSON 对象域'{"a": {"b":"foo"}}'::json->'a'{"b":"foo"}
->>int文本形式获得 JSON 数组元素'[1,2,3]'::json->>23
->>text文本形式获得 JSON 对象域'{"a":1,"b":2}'::json->>'b'2
#>text[]获取在指定路径的 JSON 对象'{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'{"c": "foo"}
#>>text[]文本形式获取在指定路径的 JSON 对象'{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'3

Note: jsonjsonb类型,这些操作符都有其并行变体。 域/元素/路径抽取操作符返回与其左手输入(jsonjsonb) 相同的类型,不过那些被指定为返回text的除外,它们的返回值会被强制 为文本。如果该 JSON 输入没有匹配请求的正确结构(例如那样的元素不存在),这些 域/元素/路径抽取操作符会返回 NULL 而不是失败。

Table 9-1中展示的标准比较操作符只对 jsonb有效,而不适合json。它们遵循在Section 8.14.4中给出的 B 树操作规则。

Table 9-41中所示,还存在一些只适合 jsonb的操作符。这些操作符中的很多可以用jsonb 操作符类索引。jsonb包含和存在语义的完整描述可参见Section 8.14.3Section 8.14.4描述了如何 用这些操作符来有效地索引jsonb数据。

Table 9-41. 额外的jsonb操作符

操作符右操作数类型描述例子
@>jsonb左边的 JSON 值是否包含右边的值?'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb
<@jsonb左边的 JSON 值是否被包含在右边的值中?'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb
?text键/元素字符串是否存在于 JSON 值中?'{"a":1, "b":2}'::jsonb ? 'b'
?|text[]这些键/元素字符串中的任何一个是否存在?'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']
?&text[]这些键/元素字符串是否都存在?'["a", "b"]'::jsonb ?& array['a', 'b']

Table 9-42展示了能用来创建json 值的函数(当前,没有用于jsonb的等效函数,但是可以把这些函数的结果 造型成jsonb)。

Table 9-42. JSON 创建函数

函数描述例子例子结果
to_json(anyelement) 把值返回为 JSON。数组和组合被(递归地)转换成数组和对象;对其他类型, 如果有从该类型到json的造型,将使用该造型函数来执行转换; 否则将产生一个 JSON 标量值。对任何一个非数值、布尔量或空值的标量类型, 将使用其文本表达,并且会对其做适当的引用及转义以便使其成为一个有效的 JSON 字符串。 to_json('Fred said "Hi."'::text)"Fred said \"Hi.\""
array_to_json(anyarray [, pretty_bool]) 把数组作为一个 JSON 数组返回。一个 PostgreSQL 多维数组会成为一个数组 的 JSON 数组。如果pretty_bool为真,将在 第 1 维度的元素之间增加换行。 array_to_json('{{1,5},{99,100}}'::int[])[[1,5],[99,100]]
row_to_json(record [, pretty_bool]) 把行作为一个 JSON 对象返回。如果pretty_bool为真,将在第1层元素之间增加换行。 row_to_json(row(1,'foo')){"f1":1,"f2":"foo"}
json_build_array(VARIADIC "any") 从一个可变参数列表构造一个可能包含异质类型的 JSON 数组。 json_build_array(1,2,'3',4,5)[1, 2, "3", 4, 5]
json_build_object(VARIADIC "any") 从一个可变参数列表构造一个 JSON 对象。通过转换,该参数列表由交替 出现的键和值构成。 json_build_object('foo',1,'bar',2){"foo": 1, "bar": 2}
json_object(text[]) 从一个文本数组构造一个 JSON 对象。该数组必须可以是具有偶数个成员的 一维数组(成员被当做交替出现的键/值对),或者是一个二维数组(每一个 内部数组刚好有 2 个元素,可以被看做是键/值对)。

json_object('{a, 1, b, "def", c, 3.5}')

json_object('{{a, 1},{b, "def"},{c, 3.5}}')

{"a": "1", "b": "def", "c": "3.5"}
json_object(keys text[], values text[]) json_object的这种形式从两个独立的数组得到键/值对。在其 他方面和一个参数的形式相同。 json_object('{a, b}', '{1,2}'){"a": "1", "b": "2"}

Note: array_to_jsonrow_to_jsonto_json 具有相同的行为,不过它们提供了更好的打印选项。针对to_json所描述 的行为同样也适用于由其他 JSON 创建函数转换的每个值。

Note: hstore扩展有一个从hstorejson 的造型,因此通过 JSON 创建函数转换的hstore值将被表示为 JSON 对象,而不是原始字符串值。

Table 9-43展示了可用来处理jsonjsonb值的函数。

Table 9-43. JSON 处理

函数返回值描述例子例子结果

json_array_length(json)

jsonb_array_length(jsonb)

int 返回最外层 JSON 数组中的元素数量。 json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')5

json_each(json)

jsonb_each(jsonb)

setof key text, value json

setof key text, value jsonb

扩展最外层的 JSON 对象成为一组键/值对。 select * from json_each('{"a":"foo", "b":"bar"}')
 key | value
-----+-------
 a   | "foo"
 b   | "bar"
 

json_each_text(json)

jsonb_each_text(jsonb)

setof key text, value text 扩展最外层的 JSON 对象成为一组键/值对。返回值将是文本类型。 select * from json_each_text('{"a":"foo", "b":"bar"}')
 key | value
-----+-------
 a   | foo
 b   | bar
 

json_extract_path(from_json json, VARIADIC path_elems text[])

jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[])

json

jsonb

返回由path_elems指向的 JSON 值(等效于#>操作符)。 json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4'){"f5":99,"f6":"foo"}

json_extract_path_text(from_json json, VARIADIC path_elems text[])

jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[])

text文本返回由path_elems指向的 JSON 值(等效于#>>操作符)。 json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6')foo

json_object_keys(json)

jsonb_object_keys(jsonb)

setof text 返回最外层 JSON 对象中的键集合。 json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')
 json_object_keys
------------------
 f1
 f2

json_populate_record(base anyelement, from_json json)

jsonb_populate_record(base anyelement, from_json jsonb)

anyelement 扩展from_json中的对象成一个行,它的列匹配由base定义的记录类型(见下文的注释)。 select * from json_populate_record(null::myrowtype, '{"a":1,"b":2}')
 a | b
---+---
 1 | 2

json_populate_recordset(base anyelement, from_json json)

jsonb_populate_recordset(base anyelement, from_json jsonb)

setof anyelement 扩展from_json中最外的对象数组为一个集合,该集合的列匹配由base定义的记录类型。 select * from json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]')
 a | b
---+---
 1 | 2
 3 | 4
 

json_array_elements(json)

jsonb_array_elements(jsonb)

setof json

setof jsonb

把一个 JSON 数组扩展成一个 JSON 值的集合。 select * from json_array_elements('[1,true, [2,false]]')
   value
-----------
 1
 true
 [2,false]

json_array_elements_text(json)

jsonb_array_elements_text(jsonb)

setof text 把一个 JSON 数组扩展成一个text值集合。 select * from json_array_elements_text('["foo", "bar"]')
   value
-----------
 foo
 bar

json_typeof(json)

jsonb_typeof(jsonb)

text 把最外层的 JSON 值的类型作为一个文本字符串返回。可能的类型是: objectarraystringnumberboolean以及nulljson_typeof('-123.4')number

json_to_record(json)

jsonb_to_record(jsonb)

record 从一个 JSON 对象(见下文的注解)构建一个任意的记录。正如所有返回record 的函数一样,调用者必须用一个AS子句显式地定义记录的结构。 select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}') as x(a int, b text, d text)
 a |    b    | d
---+---------+---
 1 | [1,2,3] |

json_to_recordset(json)

jsonb_to_recordset(jsonb)

setof record 从一个 JSON 对象数组(见下文的注解)构建一个任意的记录集合。正如所有返回record 的函数一样,调用者必须用一个AS子句显式地定义记录的结构。 select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text);
 a |  b
---+-----
 1 | foo
 2 |

Note: 很多这些函数和操作符将把 JSON 字符串中的 Unicode 转义转换成合适的单一字符。如果 输入类型是jsonb,这就没有问题,因为该转换已经完成了。但是对于json 输入,这可能会导致抛出一个错误(如Section 8.14所述)。

Note: json_populate_recordjson_populate_recordsetjson_to_recordjson_to_recordset中,来自 JSON 的 类型强制是"尽力而为"并且对于某些类型可能得不到想要的值。JSON 键会被 匹配目标行类型中相同的列名。没有出现在目标行类型中的 JSON 域将会被从输出中忽略, 并且不匹配任何 JSON 域的目标列将被简单地作为 NULL。

Note: 不要把json_typeof函数的null返回值与 SQL 的 NULL 弄混。 虽然调用json_typeof('null'::json)将会返回null,但调用 json_typeof(NULL::json)将会返回一个 SQL 的 NULL。

也可参见Section 9.20了解聚集函数json_agg,它可以把记录值聚集成 JSON。还有聚集函数json_object_agg,它可以把值对聚集成一个 JSON 对象。