PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 9. 函数和操作符 | 下一页

# 9.15. JSON 函数和操作符

表 9-40显示了可以用于这两个JSON （参阅第 8.14 节）数据类型的操作符。

表 9-40. `json`和`jsonb`操作符

操作符 | 右操作数的类型 | 描述 | 示例 | 示例结果
--- | --- | --- | --- | ---
`->` | `int` | 获取JSON数组元素（索引从0开始） | `'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2` | `{"c":"baz"}`
`->` | `text` | 通过秘钥获取JSON对象字段 | `'{"a": {"b":"foo"}}'::json->'a'` | `{"b":"foo"}`
`->>` | `int` | 获取JSON数组元素为`text` | `'[1,2,3]'::json->>2` | `3`
`->>` | `text` | 获取JSON对象字段为`text` | `'{"a":1,"b":2}'::json->>'b'` | `2`
`#>` | `text[]` | 在指定的路径获取JSON对象 | `'{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'` | `{"c": "foo"}`
`#>>` | `text[]` | 在指定的路径获取JSON对象为`text` | `'{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'` | `3`

> 注意: 有`json`和`jsonb`类型的这些操作符的并行变体。 字段/元素/路径提取操作符返回和它们的左侧输入相同的类型 （不管是`json`还是`jsonb`）， 除了那些指定返回`text`类型的操作符，它们强制值为文本类型。 如果JSON输入的结构没有正确匹配要求，那么字段/元素/路径提取操作符返回NULL， 而不是失败；例如，如果不存在这样的元素。

表 9-1 中显示的标准比较操作符可以用于`jsonb`， 但是不能用于`json`。 它们遵循第 8.14.4 节 中概述的B-tree操作符排序规则。

一些更深一步的操作符只为`jsonb`存在，在 表 9-41中显示。 许多这样的操作符可以用`jsonb`操作符类索引。 `jsonb`容器和存在语义的详细描述，请查看 第 8.14.3 节。第 8.14.4 节 描述了这些操作符如何用于有效的索引`jsonb`数据。

表 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']`

表 9-42显示了可以用于创建`json` 值的函数。（目前，对于`jsonb`来说没有等效的函数， 但是你可以转换这些函数的结果到`jsonb`。）

表 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`为 true， 将在级别-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对象的文本数组。该数组必须正好有一维偶数个数的成员， 在这种情况下，将它们看做交替的键/值对，或者两维， 这样每个内部数组正好有两个元素，它们被看做是键/值对。 | `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"}`

> 注意: `array_to_json`和`row_to_json`的行为与 `to_json`相同，除了提供了一个整齐打印的选项。 描述的`to_json`的行为也应用到每个由其他JSON创建函数转换的单独的值。

> 注意: hstore扩展从`hstore`转换到`json`， 所以通过JSON创建函数转换的`hstore`值将表示为JSON对象， 而不是作为原始的字符串值。

表 9-43显示了可以用于处理 `json`和`jsonb`值的函数。

表 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对象为一组键/值对。返回值为`text`类型。 | `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` | 作为`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值的类型。 可能的类型有 Returns the type of the outermost JSON value as a text string. Possible types are`object`、`array`、`string`、 `number`、`boolean`和`null`。 | `json_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 |

> 注意: 许多这些函数和操作符将转换JSON字符串中的Unicode转义到相应的单字符。 如果输入的类型是`jsonb`，那么这将不是一个问题，因为转换早已完成； 但是如果是`json`输入，那么会导致抛出一个错误，就像 第 8.14 节中记录的那样。

> 注意: 在`json_populate_record`、`json_populate_recordset`、 `json_to_record`和`json_to_recordset`中， JSON的类型转换是"尽力而为"的，并且对某些类型来说可能不会产生期望值。 JSON键匹配目标行类型中完全相同的字段名。没有出现在目标行类型中的JSON字段将从输出中省略， 并且不匹配任何JSON字段的目标字段将是NULL。

> 注意: `json_typeof`函数的`null`返回值不应该与SQL NULL混淆。 当调用`json_typeof('null'::json)`时，将返回`null`， 调用`json_typeof(NULL::json)`时，返回SQL NULL。

参阅第 9.20 节获取有关聚合函数`json_agg` 的信息，`json_agg`聚合记录值为JSON， 聚合函数`json_object_agg`聚合值对到JSON对象。

上一页 | 起始页 | 下一页
XML 函数 | 上一级 | 序列操作函数