Improve user-facing JSON documentation.
I started out with the intention of just fixing the info about the jsonb operator classes, but soon found myself copy-editing most of the JSON material. Hopefully it's more readable now.
This commit is contained in:
parent
0ca6bda8e7
commit
0b92a77c17
@ -10081,7 +10081,7 @@ table2-mapping
|
|||||||
|
|
||||||
<indexterm zone="functions-json">
|
<indexterm zone="functions-json">
|
||||||
<primary>JSON</primary>
|
<primary>JSON</primary>
|
||||||
<secondary>Functions and operators</secondary>
|
<secondary>functions and operators</secondary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -10105,43 +10105,43 @@ table2-mapping
|
|||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>-></literal></entry>
|
<entry><literal>-></literal></entry>
|
||||||
<entry>int</entry>
|
<entry><type>int</type></entry>
|
||||||
<entry>Get JSON array element</entry>
|
<entry>Get JSON array element</entry>
|
||||||
<entry><literal>'[{"a":"foo"},{"a":"bar"},{"a":"baz"}]'::json->2</literal></entry>
|
<entry><literal>'[{"a":"foo"},{"a":"bar"},{"a":"baz"}]'::json->2</literal></entry>
|
||||||
<entry><literal>{"a":"baz"}</literal></entry>
|
<entry><literal>{"a":"baz"}</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>-></literal></entry>
|
<entry><literal>-></literal></entry>
|
||||||
<entry>text</entry>
|
<entry><type>text</type></entry>
|
||||||
<entry>Get JSON object field</entry>
|
<entry>Get JSON object field</entry>
|
||||||
<entry><literal>'{"a": {"b":"foo"}}'::json->'a'</literal></entry>
|
<entry><literal>'{"a": {"b":"foo"}}'::json->'a'</literal></entry>
|
||||||
<entry><literal>{"b":"foo"}</literal></entry>
|
<entry><literal>{"b":"foo"}</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>->></literal></entry>
|
<entry><literal>->></literal></entry>
|
||||||
<entry>int</entry>
|
<entry><type>int</type></entry>
|
||||||
<entry>Get JSON array element as text</entry>
|
<entry>Get JSON array element as <type>text</></entry>
|
||||||
<entry><literal>'[1,2,3]'::json->>2</literal></entry>
|
<entry><literal>'[1,2,3]'::json->>2</literal></entry>
|
||||||
<entry><literal>3</literal></entry>
|
<entry><literal>3</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>->></literal></entry>
|
<entry><literal>->></literal></entry>
|
||||||
<entry>text</entry>
|
<entry><type>text</type></entry>
|
||||||
<entry>Get JSON object field as text</entry>
|
<entry>Get JSON object field as <type>text</></entry>
|
||||||
<entry><literal>'{"a":1,"b":2}'::json->>'b'</literal></entry>
|
<entry><literal>'{"a":1,"b":2}'::json->>'b'</literal></entry>
|
||||||
<entry><literal>2</literal></entry>
|
<entry><literal>2</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>#></literal></entry>
|
<entry><literal>#></literal></entry>
|
||||||
<entry>text[]</entry>
|
<entry><type>text[]</type></entry>
|
||||||
<entry>Get JSON object at specified path</entry>
|
<entry>Get JSON object at specified path</entry>
|
||||||
<entry><literal>'{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'</literal></entry>
|
<entry><literal>'{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'</literal></entry>
|
||||||
<entry><literal>{"c": "foo"}</literal></entry>
|
<entry><literal>{"c": "foo"}</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>#>></literal></entry>
|
<entry><literal>#>></literal></entry>
|
||||||
<entry>text[]</entry>
|
<entry><type>text[]</type></entry>
|
||||||
<entry>Get JSON object at specified path as text</entry>
|
<entry>Get JSON object at specified path as <type>text</></entry>
|
||||||
<entry><literal>'{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'</literal></entry>
|
<entry><literal>'{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'</literal></entry>
|
||||||
<entry><literal>3</literal></entry>
|
<entry><literal>3</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
@ -10152,14 +10152,17 @@ table2-mapping
|
|||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
There are parallel variants of these operators for both the
|
There are parallel variants of these operators for both the
|
||||||
<type>json</type> and <type>jsonb</type> types. In addition to
|
<type>json</type> and <type>jsonb</type> types. The operators
|
||||||
those operators common to both types, a further set of operators
|
return the same type as their left-hand input (either <type>json</type>
|
||||||
exists for <type>jsonb</type> (which comprise the default
|
or <type>jsonb</type>), except for those specified as
|
||||||
<acronym>GIN</acronym> operator class).
|
returning <type>text</>, which coerce the value to text.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
<para>
|
<para>
|
||||||
The following are <type>jsonb</>-only operators, used by
|
In addition to those operators common to both types, some additional
|
||||||
|
operators exist only for <type>jsonb</type>, as shown
|
||||||
|
in <xref linkend="functions-jsonb-op-table">.
|
||||||
|
Many of these operators can be indexed by
|
||||||
<type>jsonb</> operator classes. For a full description of
|
<type>jsonb</> operator classes. For a full description of
|
||||||
<type>jsonb</> containment semantics and nesting, see <xref
|
<type>jsonb</> containment semantics and nesting, see <xref
|
||||||
linkend="json-containment">. <xref linkend="json-indexing">
|
linkend="json-containment">. <xref linkend="json-indexing">
|
||||||
@ -10167,7 +10170,7 @@ table2-mapping
|
|||||||
<type>jsonb</>.
|
<type>jsonb</>.
|
||||||
</para>
|
</para>
|
||||||
<table id="functions-jsonb-op-table">
|
<table id="functions-jsonb-op-table">
|
||||||
<title>Additonal JSONB Operators</title>
|
<title>Additional <type>jsonb</> Operators</title>
|
||||||
<tgroup cols="4">
|
<tgroup cols="4">
|
||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
@ -10180,37 +10183,38 @@ table2-mapping
|
|||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>=</literal></entry>
|
<entry><literal>=</literal></entry>
|
||||||
<entry>jsonb</entry>
|
<entry><type>jsonb</type></entry>
|
||||||
<entry>Is the jsonb equal to this jsonb?</entry>
|
<entry>Are the two JSON values equal?</entry>
|
||||||
<entry><literal>'[1,2,3]'::jsonb = '[1,2,3]'::jsonb</literal></entry>
|
<entry><literal>'[1,2,3]'::jsonb = '[1,2,3]'::jsonb</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>@></literal></entry>
|
<entry><literal>@></literal></entry>
|
||||||
<entry>jsonb</entry>
|
<entry><type>jsonb</type></entry>
|
||||||
<entry>Does the jsonb contain within it this jsonb?</entry>
|
<entry>Does the left JSON value contain within it the right value?</entry>
|
||||||
<entry><literal>'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb</literal></entry>
|
<entry><literal>'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal><@</literal></entry>
|
<entry><literal><@</literal></entry>
|
||||||
<entry>jsonb</entry>
|
<entry><type>jsonb</type></entry>
|
||||||
<entry>Does the jsonb have contained within it this jsonb?</entry>
|
<entry>Is the left JSON value contained within the right value?</entry>
|
||||||
<entry><literal>'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb</literal></entry>
|
<entry><literal>'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>?</literal></entry>
|
<entry><literal>?</literal></entry>
|
||||||
<entry>text</entry>
|
<entry><type>text</type></entry>
|
||||||
<entry>Does this key/element <emphasis>string</emphasis> exist?</entry>
|
<entry>Does the key/element <emphasis>string</emphasis> exist within
|
||||||
|
the JSON value?</entry>
|
||||||
<entry><literal>'{"a":1, "b":2}'::jsonb ? 'b'</literal></entry>
|
<entry><literal>'{"a":1, "b":2}'::jsonb ? 'b'</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>?|</literal></entry>
|
<entry><literal>?|</literal></entry>
|
||||||
<entry>text[]</entry>
|
<entry><type>text[]</type></entry>
|
||||||
<entry>Do any of these key/element <emphasis>strings</emphasis> exist?</entry>
|
<entry>Do any of these key/element <emphasis>strings</emphasis> exist?</entry>
|
||||||
<entry><literal>'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']</literal></entry>
|
<entry><literal>'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>?&</literal></entry>
|
<entry><literal>?&</literal></entry>
|
||||||
<entry>text[]</entry>
|
<entry><type>text[]</type></entry>
|
||||||
<entry>Do all of these key/element <emphasis>strings</emphasis> exist?</entry>
|
<entry>Do all of these key/element <emphasis>strings</emphasis> exist?</entry>
|
||||||
<entry><literal>'["a", "b"]'::jsonb ?& array['a', 'b']</literal></entry>
|
<entry><literal>'["a", "b"]'::jsonb ?& array['a', 'b']</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
@ -10218,15 +10222,11 @@ table2-mapping
|
|||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!--
|
<para>
|
||||||
The release notes contain a reference to "functions-json-table". Since
|
|
||||||
that table is now split in two, the id has been parked here so we don't
|
|
||||||
have to change the release notes.
|
|
||||||
-->
|
|
||||||
<para id="functions-json-table">
|
|
||||||
<xref linkend="functions-json-creation-table"> shows the functions that are
|
<xref linkend="functions-json-creation-table"> shows the functions that are
|
||||||
available for creating <type>json</type> values.
|
available for creating <type>json</type> values.
|
||||||
(see <xref linkend="datatype-json">)
|
(Currently, there are no equivalent functions for <type>jsonb</>, but you
|
||||||
|
can cast the result of one of these functions to <type>jsonb</>.)
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@ -10250,11 +10250,10 @@ table2-mapping
|
|||||||
|
|
||||||
<table id="functions-json-creation-table">
|
<table id="functions-json-creation-table">
|
||||||
<title>JSON Creation Functions</title>
|
<title>JSON Creation Functions</title>
|
||||||
<tgroup cols="5">
|
<tgroup cols="4">
|
||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
<entry>Function</entry>
|
<entry>Function</entry>
|
||||||
<entry>Return Type</entry>
|
|
||||||
<entry>Description</entry>
|
<entry>Description</entry>
|
||||||
<entry>Example</entry>
|
<entry>Example</entry>
|
||||||
<entry>Example Result</entry>
|
<entry>Example Result</entry>
|
||||||
@ -10265,7 +10264,6 @@ table2-mapping
|
|||||||
<entry>
|
<entry>
|
||||||
<literal>array_to_json(anyarray [, pretty_bool])</literal>
|
<literal>array_to_json(anyarray [, pretty_bool])</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
Returns the array as JSON. A PostgreSQL multidimensional array
|
Returns the array as JSON. A PostgreSQL multidimensional array
|
||||||
becomes a JSON array of arrays. Line feeds will be added between
|
becomes a JSON array of arrays. Line feeds will be added between
|
||||||
@ -10278,7 +10276,6 @@ table2-mapping
|
|||||||
<entry>
|
<entry>
|
||||||
<literal>row_to_json(record [, pretty_bool])</literal>
|
<literal>row_to_json(record [, pretty_bool])</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
Returns the row as JSON. Line feeds will be added between level
|
Returns the row as JSON. Line feeds will be added between level
|
||||||
1 elements if <parameter>pretty_bool</parameter> is true.
|
1 elements if <parameter>pretty_bool</parameter> is true.
|
||||||
@ -10290,7 +10287,6 @@ table2-mapping
|
|||||||
<entry>
|
<entry>
|
||||||
<literal>to_json(anyelement)</literal>
|
<literal>to_json(anyelement)</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
Returns the value as JSON. If the data type is not built in, and there
|
Returns the value as JSON. If the data type is not built in, and there
|
||||||
is a cast from the type to <type>json</type>, the cast function will be used to
|
is a cast from the type to <type>json</type>, the cast function will be used to
|
||||||
@ -10305,43 +10301,29 @@ table2-mapping
|
|||||||
<entry>
|
<entry>
|
||||||
<literal>json_build_array(VARIADIC "any")</literal>
|
<literal>json_build_array(VARIADIC "any")</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
Builds a heterogeneously-typed json array out of a variadic argument list.
|
Builds a possibly-heterogeneously-typed JSON array out of a variadic
|
||||||
</entry>
|
argument list.
|
||||||
<entry><literal>SELECT json_build_array(1,2,'3',4,5);</literal></entry>
|
|
||||||
<entry>
|
|
||||||
<programlisting>
|
|
||||||
json_build_array
|
|
||||||
-------------------
|
|
||||||
[1, 2, "3", 4, 5]
|
|
||||||
</programlisting>
|
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry><literal>json_build_array(1,2,'3',4,5)</literal></entry>
|
||||||
|
<entry><literal>[1, 2, "3", 4, 5]</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<literal>json_build_object(VARIADIC "any")</literal>
|
<literal>json_build_object(VARIADIC "any")</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
Builds a JSON array out of a variadic argument list. By
|
Builds a JSON object out of a variadic argument list. By
|
||||||
convention, the object is constructed out of alternating
|
convention, the argument list consists of alternating
|
||||||
name/value arguments.
|
names and values.
|
||||||
</entry>
|
|
||||||
<entry><literal>SELECT json_build_object('foo',1,'bar',2);</literal></entry>
|
|
||||||
<entry>
|
|
||||||
<programlisting>
|
|
||||||
json_build_object
|
|
||||||
------------------------
|
|
||||||
{"foo" : 1, "bar" : 2}
|
|
||||||
</programlisting>
|
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry><literal>json_build_object('foo',1,'bar',2)</literal></entry>
|
||||||
|
<entry><literal>{"foo" : 1, "bar" : 2}</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<literal>json_object(text[])</literal>
|
<literal>json_object(text[])</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
Builds a JSON object out of a text array. The array must have either
|
Builds a JSON object out of a text array. The array must have either
|
||||||
exactly one dimension with an even number of members, in which case
|
exactly one dimension with an even number of members, in which case
|
||||||
@ -10349,42 +10331,28 @@ table2-mapping
|
|||||||
such that each inner array has exactly two elements, which
|
such that each inner array has exactly two elements, which
|
||||||
are taken as a name/value pair.
|
are taken as a name/value pair.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>select * from json_object('{a, 1, b, "def", c, 3.5}') or <literal>select json_object('{{a, 1},{b, "def"},{c, 3.5}}')</literal></literal></entry>
|
<entry><para><literal>json_object('{a, 1, b, "def", c, 3.5}')</></para>
|
||||||
<entry>
|
<para><literal>json_object('{{a, 1},{b, "def"},{c, 3.5}}')</></para></entry>
|
||||||
<programlisting>
|
<entry><literal>{"a" : "1", "b" : "def", "c" : "3.5"}</literal></entry>
|
||||||
json_object
|
|
||||||
---------------------------------------
|
|
||||||
{"a" : "1", "b" : "def", "c" : "3.5"}
|
|
||||||
</programlisting>
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<literal>json_object(keys text[], values text[])</literal>
|
<literal>json_object(keys text[], values text[])</literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>json</type></entry>
|
|
||||||
<entry>
|
<entry>
|
||||||
The two-argument form of JSON object takes keys and values pairwise from two separate
|
This form of <function>json_object</> takes keys and values pairwise from two separate
|
||||||
arrays. In all other respects it is identical to the one-argument form.
|
arrays. In all other respects it is identical to the one-argument form.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>select json_object('{a, b}', '{1,2}');</literal></entry>
|
<entry><literal>json_object('{a, b}', '{1,2}')</literal></entry>
|
||||||
<entry>
|
<entry><literal>{"a" : "1", "b" : "2"}</literal></entry>
|
||||||
<programlisting>
|
|
||||||
json_object
|
|
||||||
------------------------
|
|
||||||
{"a" : "1", "b" : "2"}
|
|
||||||
</programlisting>
|
|
||||||
</entry>
|
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="functions-json-processing-table"> shows the functions that
|
<xref linkend="functions-json-processing-table"> shows the functions that
|
||||||
are available for processing <type>json</type> and <type>jsonb</type> values.
|
are available for processing <type>json</type> and <type>jsonb</type> values.
|
||||||
(see <xref linkend="datatype-json">)
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@ -10494,8 +10462,8 @@ table2-mapping
|
|||||||
<entry><para><literal>json_each(json)</literal>
|
<entry><para><literal>json_each(json)</literal>
|
||||||
</para><para><literal>jsonb_each(jsonb)</literal>
|
</para><para><literal>jsonb_each(jsonb)</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry><para><literal>SETOF key text, value json</literal>
|
<entry><para><literal>setof key text, value json</literal>
|
||||||
</para><para><literal>SETOF key text, value jsonb</literal>
|
</para><para><literal>setof key text, value jsonb</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Expands the outermost JSON object into a set of key/value pairs.
|
Expands the outermost JSON object into a set of key/value pairs.
|
||||||
@ -10514,10 +10482,10 @@ table2-mapping
|
|||||||
<entry><para><literal>json_each_text(from_json json)</literal>
|
<entry><para><literal>json_each_text(from_json json)</literal>
|
||||||
</para><para><literal>jsonb_each_text(from_json jsonb)</literal>
|
</para><para><literal>jsonb_each_text(from_json jsonb)</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry><type>SETOF key text, value text</type></entry>
|
<entry><type>setof key text, value text</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Expands the outermost JSON object into a set of key/value pairs. The
|
Expands the outermost JSON object into a set of key/value pairs. The
|
||||||
returned value will be of type text.
|
returned value will be of type <type>text</>.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>select * from json_each_text('{"a":"foo", "b":"bar"}')</literal></entry>
|
<entry><literal>select * from json_each_text('{"a":"foo", "b":"bar"}')</literal></entry>
|
||||||
<entry>
|
<entry>
|
||||||
@ -10556,7 +10524,7 @@ table2-mapping
|
|||||||
<entry><para><literal>json_object_keys(json)</literal>
|
<entry><para><literal>json_object_keys(json)</literal>
|
||||||
</para><para><literal>jsonb_object_keys(jsonb)</literal>
|
</para><para><literal>jsonb_object_keys(jsonb)</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry><type>SETOF text</type></entry>
|
<entry><type>setof text</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Returns set of keys in the JSON object. Only the <quote>outer</quote> object will be displayed.
|
Returns set of keys in the JSON object. Only the <quote>outer</quote> object will be displayed.
|
||||||
</entry>
|
</entry>
|
||||||
@ -10595,7 +10563,7 @@ table2-mapping
|
|||||||
<entry><para><literal>json_populate_recordset(base anyelement, from_json json, [, use_json_as_text bool=false])</literal>
|
<entry><para><literal>json_populate_recordset(base anyelement, from_json json, [, use_json_as_text bool=false])</literal>
|
||||||
</para><para><literal>jsonb_populate_recordset(base anyelement, from_json jsonb, [, use_json_as_text bool=false])</literal>
|
</para><para><literal>jsonb_populate_recordset(base anyelement, from_json jsonb, [, use_json_as_text bool=false])</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry><type>SETOF anyelement</type></entry>
|
<entry><type>setof anyelement</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Expands the outermost set of objects in <replaceable>from_json</replaceable> to a set
|
Expands the outermost set of objects in <replaceable>from_json</replaceable> to a set
|
||||||
whose columns match the record type defined by base.
|
whose columns match the record type defined by base.
|
||||||
@ -10618,13 +10586,13 @@ table2-mapping
|
|||||||
<entry><para><literal>json_array_elements(json)</literal>
|
<entry><para><literal>json_array_elements(json)</literal>
|
||||||
</para><para><literal>jsonb_array_elements(jsonb)</literal>
|
</para><para><literal>jsonb_array_elements(jsonb)</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry><para><type>SETOF json</type>
|
<entry><para><type>setof json</type>
|
||||||
</para><para><type>SETOF jsonb</type>
|
</para><para><type>setof jsonb</type>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Expands a JSON array to a set of JSON values.
|
Expands a JSON array to a set of JSON values.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>SELECT * FROM json_array_elements('[1,true, [2,false]]')</literal></entry>
|
<entry><literal>select * from json_array_elements('[1,true, [2,false]]')</literal></entry>
|
||||||
<entry>
|
<entry>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
value
|
value
|
||||||
@ -10639,11 +10607,11 @@ table2-mapping
|
|||||||
<entry><para><literal>json_array_elements_text(json)</literal>
|
<entry><para><literal>json_array_elements_text(json)</literal>
|
||||||
</para><para><literal>jsonb_array_elements_text(jsonb)</literal>
|
</para><para><literal>jsonb_array_elements_text(jsonb)</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
<entry><type>SETOF text</type></entry>
|
<entry><type>setof text</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Expands a JSON array to a set of text values.
|
Expands a JSON array to a set of <type>text</> values.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>SELECT * FROM json_array_elements_text('["foo", "bar"]')</literal></entry>
|
<entry><literal>select * from json_array_elements_text('["foo", "bar"]')</literal></entry>
|
||||||
<entry>
|
<entry>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
value
|
value
|
||||||
@ -10674,9 +10642,9 @@ table2-mapping
|
|||||||
<entry><type>record</type></entry>
|
<entry><type>record</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Returns an arbitrary record from a JSON object. As with all functions
|
Returns an arbitrary record from a JSON object. As with all functions
|
||||||
returning 'record', the caller must explicitly define the structure of the record
|
returning <type>record</>, the caller must explicitly define the structure of the record
|
||||||
when making the call. The input JSON must be an object, not a scalar or an array.
|
when making the call. The input JSON must be an object, not a scalar or an array.
|
||||||
If nested_as_text is true, the function coerces nested complex elements to text.
|
If <literal>nested_as_text</> is true, the function coerces nested complex elements to text.
|
||||||
Also, see notes below on columns and types.
|
Also, see notes below on columns and types.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}',true) as x(a int, b text, d text) </literal></entry>
|
<entry><literal>select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}',true) as x(a int, b text, d text) </literal></entry>
|
||||||
@ -10695,9 +10663,9 @@ table2-mapping
|
|||||||
<entry><type>setof record</type></entry>
|
<entry><type>setof record</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Returns an arbitrary set of records from a JSON object. As with
|
Returns an arbitrary set of records from a JSON object. As with
|
||||||
json_to_record, the structure of the record must be explicitly defined when making the
|
<function>json_to_record</>, the structure of the record must be explicitly defined when making the
|
||||||
call. However, with json_to_recordset the input JSON must be an array containing
|
call. However, with <function>json_to_recordset</> the input JSON must be an array containing
|
||||||
objects. nested_as_text works as with json_to_record.
|
objects. <literal>nested_as_text</> works as with <function>json_to_record</>.
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]',true) as x(a int, b text);</literal></entry>
|
<entry><literal>select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]',true) as x(a int, b text);</literal></entry>
|
||||||
<entry>
|
<entry>
|
||||||
@ -10715,56 +10683,60 @@ table2-mapping
|
|||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The <type>json</type> functions and operators can impose stricter validity requirements
|
The <type>json</type> functions and operators can impose stricter
|
||||||
than the type's input functions. In particular, they check much more closely that any use
|
validity requirements than the JSON types' input functions do. In
|
||||||
of Unicode surrogate pairs to designate characters outside the Unicode Basic Multilingual
|
particular, they check much more closely that any use of Unicode
|
||||||
Plane is correct.
|
surrogate pairs to designate characters outside the Unicode Basic
|
||||||
|
Multilingual Plane is correct.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
Many of these functions and operators will convert Unicode escapes
|
Many of these functions and operators will convert Unicode escapes in
|
||||||
in the JSON text to the appropriate UTF8 character when the database encoding is UTF8. In
|
the JSON text to the appropriate UTF8 character when the database
|
||||||
other encodings the escape sequence must be for an ASCII character, and any other code point
|
encoding is UTF8. In other encodings the escape sequence must be for an
|
||||||
in a Unicode escape sequence will result in an error.
|
ASCII character, and any other code point in a Unicode escape sequence
|
||||||
In general, it is best to avoid mixing Unicode escapes in JSON with a non-UTF8 database
|
will result in an error. In general, it is best to avoid mixing Unicode
|
||||||
encoding, if possible.
|
escapes in JSON with a non-UTF8 database encoding, if possible.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
In json_to_record and json_to_recordset, type-coercion from the JSON is
|
In <function>json_to_record</> and <function>json_to_recordset</>,
|
||||||
"best effort" and may not result in desired values for some types. JSON
|
type coercion from the JSON is <quote>best effort</> and may not result
|
||||||
elements are matched to identical field names in the record definition,
|
in desired values for some types. JSON elements are matched to
|
||||||
and elements which do not exist in the JSON will simply be NULL. JSON
|
identical field names in the record definition, and elements which do
|
||||||
elements which are not defined in the record template will
|
not exist in the JSON will simply be NULL. JSON elements which are not
|
||||||
be omitted from the output.
|
defined in the record template will be omitted from the output.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The <xref linkend="hstore"> extension has a cast from <type>hstore</type> to
|
The <xref linkend="hstore"> extension has a cast
|
||||||
<type>json</type>, so that converted <type>hstore</type> values are represented as JSON objects,
|
from <type>hstore</type> to <type>json</type>, so that
|
||||||
|
converted <type>hstore</type> values are represented as JSON objects,
|
||||||
not as string values.
|
not as string values.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The <literal>json_typeof</> function's <literal>null</> return value should not be confused
|
The <literal>json_typeof</> function's <literal>null</> return value
|
||||||
with a SQL NULL. While calling <literal>json_typeof('null'::json)</> will return <literal>null</>,
|
should not be confused with a SQL NULL. While
|
||||||
calling <literal>json_typeof(NULL::json)</> will return a SQL NULL.
|
calling <literal>json_typeof('null'::json)</> will
|
||||||
|
return <literal>null</>, calling <literal>json_typeof(NULL::json)</>
|
||||||
|
will return a SQL NULL.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
See also <xref linkend="functions-aggregate"> about the aggregate
|
See also <xref linkend="functions-aggregate"> for the aggregate
|
||||||
function <function>json_agg</function> which aggregates record
|
function <function>json_agg</function> which aggregates record
|
||||||
values as JSON efficiently, and the aggregate function
|
values as JSON, and the aggregate function
|
||||||
<function>json_object_agg</function>, which aggregates pairs of values
|
<function>json_object_agg</function> which aggregates pairs of values
|
||||||
into a JSON object.
|
into a JSON object.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
@ -416,7 +416,7 @@
|
|||||||
<para>
|
<para>
|
||||||
Of the two operator classes for type <type>jsonb</>, <literal>jsonb_ops</>
|
Of the two operator classes for type <type>jsonb</>, <literal>jsonb_ops</>
|
||||||
is the default. <literal>jsonb_hash_ops</> supports fewer operators but
|
is the default. <literal>jsonb_hash_ops</> supports fewer operators but
|
||||||
will work with larger indexed values than <literal>jsonb_ops</> can support.
|
offers better performance for those operators.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
@ -15,118 +15,148 @@
|
|||||||
JSON data types are for storing JSON (JavaScript Object Notation)
|
JSON data types are for storing JSON (JavaScript Object Notation)
|
||||||
data, as specified in <ulink url="http://rfc7159.net/rfc7159">RFC
|
data, as specified in <ulink url="http://rfc7159.net/rfc7159">RFC
|
||||||
7159</ulink>. Such data can also be stored as <type>text</type>, but
|
7159</ulink>. Such data can also be stored as <type>text</type>, but
|
||||||
both JSON data types have the advantage of enforcing that each
|
the JSON data types have the advantage of enforcing that each
|
||||||
stored value is a valid JSON value. There are also related support
|
stored value is valid according to the JSON rules. There are also
|
||||||
functions available; see <xref linkend="functions-json">.
|
assorted JSON-specific functions available for data stored in these
|
||||||
|
data types; see <xref linkend="functions-json">.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
There are two JSON data types: <type>json</> and <type>jsonb</>.
|
There are two JSON data types: <type>json</> and <type>jsonb</>.
|
||||||
Both accept <emphasis>almost</emphasis> identical sets of values as
|
They accept <emphasis>almost</> identical sets of values as
|
||||||
input. The major practical difference is one of efficiency. The
|
input. The major practical difference is one of efficiency. The
|
||||||
<type>json</> data type stores an exact copy of the input text,
|
<type>json</> data type stores an exact copy of the input text,
|
||||||
which processing functions must continually reparse, while
|
which processing functions must reparse on each execution; while
|
||||||
<type>jsonb</> data is stored in a decomposed binary format that
|
<type>jsonb</> data is stored in a decomposed binary format that
|
||||||
makes it slightly less efficient to input due to added serialization
|
makes it slightly slower to input due to added conversion
|
||||||
overhead, but significantly faster to process, since it never needs
|
overhead, but significantly faster to process, since it never needs
|
||||||
reparsing. <type>jsonb</> also supports advanced
|
reparsing. <type>jsonb</> also supports indexing, which can be a
|
||||||
<acronym>GIN</acronym> indexing, which is a further significant
|
significant advantage.
|
||||||
advantage.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The other difference between the types is that the <type>json</>
|
Because the <type>json</> type stores an exact copy of the input text, it
|
||||||
type is guaranteed to contain an exact copy of the input, including
|
will preserve semantically-insignificant white space between tokens, as
|
||||||
preservation of semantically insignificant white space, and the
|
well as the order of keys within JSON objects. Also, if a JSON object
|
||||||
order of keys within JSON objects (although <type>jsonb</> will
|
within the value contains the same key more than once, all the key/value
|
||||||
preserve trailing zeros within a JSON number). Also, because the
|
pairs are kept. (The processing functions consider the last value as the
|
||||||
exact text is kept, if a JSON object within the value contains the
|
operative one.) By contrast, <type>jsonb</> does not preserve white
|
||||||
same key more than once, and has been stored using the <type>json</>
|
space, does not preserve the order of object keys, and does not keep
|
||||||
type, all the key/value pairs are kept. In that case, the
|
duplicate object keys. Only the last value for a key specified in the
|
||||||
processing functions consider the last value as the operative one.
|
input is kept. <type>jsonb</> will preserve trailing zeros within a JSON
|
||||||
By contrast, <type>jsonb</> does not preserve white space, does not
|
number, even though those are semantically insignificant for purposes such
|
||||||
preserve the order of object keys, and does not keep duplicate
|
as equality checks.
|
||||||
object keys. Only the last value for a key specified in the input
|
|
||||||
is kept.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
In general, most applications will prefer to store JSON data as
|
In general, most applications should prefer to store JSON data as
|
||||||
<type>jsonb</>, unless there are quite specialized needs.
|
<type>jsonb</>, unless there are quite specialized needs, such as
|
||||||
|
legacy assumptions about ordering of object keys.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<productname>PostgreSQL</productname> allows only one server
|
<productname>PostgreSQL</productname> allows only one character set
|
||||||
encoding per database. It is therefore not possible for the JSON
|
encoding per database. It is therefore not possible for the JSON
|
||||||
types to conform rigidly to the specification unless the server
|
types to conform rigidly to the JSON specification unless the database
|
||||||
encoding is UTF-8. Attempts to directly include characters which
|
encoding is UTF-8. Attempts to directly include characters which
|
||||||
cannot be represented in the server encoding will fail; conversely,
|
cannot be represented in the database encoding will fail; conversely,
|
||||||
characters which can be represented in the server encoding but not
|
characters which can be represented in the database encoding but not
|
||||||
in UTF-8 will be allowed. <literal>\uXXXX</literal> escapes are
|
in UTF-8 will be allowed. <literal>\uXXXX</literal> escapes are
|
||||||
allowed regardless of the server encoding, and are checked only for
|
allowed regardless of the database encoding, and are checked only for
|
||||||
syntactic correctness.
|
syntactic correctness.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2 id="json-types">
|
<sect2 id="json-types">
|
||||||
<title>Mapping of RFC-7159/JSON Primitive Types to <productname>PostgreSQL</productname> Types</title>
|
<title>Mapping of RFC-7159/JSON Primitive Types to <productname>PostgreSQL</productname> Types</title>
|
||||||
<table id="json-type-mapping-table">
|
<table id="json-type-mapping-table">
|
||||||
<title>Mapping of type correspondence, notes</title>
|
<title>JSON scalar types and corresponding <productname>PostgreSQL</productname> types</title>
|
||||||
<tgroup cols="3">
|
<tgroup cols="3">
|
||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
<entry><productname>PostgreSQL</productname> type</entry>
|
|
||||||
<entry>RFC-7159/JSON primitive type</entry>
|
<entry>RFC-7159/JSON primitive type</entry>
|
||||||
|
<entry><productname>PostgreSQL</productname> type</entry>
|
||||||
<entry>Notes</entry>
|
<entry>Notes</entry>
|
||||||
</row>
|
</row>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry><type>text</></entry>
|
|
||||||
<entry><type>string</></entry>
|
<entry><type>string</></entry>
|
||||||
<entry>See general introductory notes on encoding and JSON</entry>
|
<entry><type>text</></entry>
|
||||||
|
<entry>See introductory notes on JSON and encoding</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><type>numeric</></entry>
|
|
||||||
<entry><type>number</></entry>
|
<entry><type>number</></entry>
|
||||||
|
<entry><type>numeric</></entry>
|
||||||
<entry><literal>NaN</literal> and <literal>infinity</literal> values are disallowed</entry>
|
<entry><literal>NaN</literal> and <literal>infinity</literal> values are disallowed</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><type>boolean</></entry>
|
<entry><type>boolean</></entry>
|
||||||
<entry><type>boolean</></entry>
|
<entry><type>boolean</></entry>
|
||||||
<entry>Only lowercase <literal>true</literal> and <literal>false</literal> values are accepted</entry>
|
<entry>Only lowercase <literal>true</literal> and <literal>false</literal> spellings are accepted</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><type>unknown</></entry>
|
|
||||||
<entry><type>null</></entry>
|
<entry><type>null</></entry>
|
||||||
<entry>SQL <literal>NULL</literal> is orthogonal. NULL semantics do not apply.</entry>
|
<entry>(none)</entry>
|
||||||
|
<entry>SQL <literal>NULL</literal> is a different concept</entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
<para>
|
<para>
|
||||||
Primitive types described by <acronym>RFC</> 7159 are effectively
|
When converting textual JSON input into <type>jsonb</>,
|
||||||
internally mapped onto native
|
the primitive types described by <acronym>RFC</> 7159 are effectively
|
||||||
<productname>PostgreSQL</productname> types. Therefore, there are
|
mapped onto native
|
||||||
|
<productname>PostgreSQL</productname> types, as shown in
|
||||||
|
<xref linkend="json-type-mapping-table">. Therefore, there are
|
||||||
some very minor additional constraints on what constitutes valid
|
some very minor additional constraints on what constitutes valid
|
||||||
<type>jsonb</type> that do not apply to the <type>json</type>
|
<type>jsonb</type> that do not apply to the <type>json</type>
|
||||||
type, or to JSON in the abstract, that pertain to limits on what
|
type, nor to JSON in the abstract, corresponding to limits on what
|
||||||
can be represented by the underlying type system. These
|
can be represented by the underlying data type. Specifically,
|
||||||
|
<type>jsonb</> will reject numbers that are outside the range of
|
||||||
|
the <productname>PostgreSQL</productname> <type>numeric</> data type,
|
||||||
|
while <type>json</> will not. Such
|
||||||
implementation-defined restrictions are permitted by
|
implementation-defined restrictions are permitted by
|
||||||
<acronym>RFC</> 7159. However, in practice problems are far more
|
<acronym>RFC</> 7159. However, in practice such problems are far more
|
||||||
likely to occur in other implementations which internally
|
likely to occur in other implementations, as it is common to
|
||||||
represent the <type>number</> JSON primitive type as IEEE 754
|
represent the <type>number</> JSON primitive type as IEEE 754
|
||||||
double precision floating point values, which <acronym>RFC</> 7159
|
double precision floating point (which <acronym>RFC</> 7159
|
||||||
explicitly anticipates and allows for. When using JSON as an
|
explicitly anticipates and allows for). When using JSON as an
|
||||||
interchange format with such systems, the danger of losing numeric
|
interchange format with such systems, the danger of losing numeric
|
||||||
precision in respect of data originally stored by
|
precision compared to data originally stored by
|
||||||
<productname>PostgreSQL</productname> should be considered.
|
<productname>PostgreSQL</productname> should be considered.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
Conversely, as noted above there are some minor restrictions on
|
|
||||||
the input format of JSON primitive types that do not apply to
|
|
||||||
corresponding <productname>PostgreSQL</productname> types.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Conversely, as noted in the table there are some minor restrictions on
|
||||||
|
the input format of JSON primitive types that do not apply to
|
||||||
|
the corresponding <productname>PostgreSQL</productname> types.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="json-keys-elements">
|
||||||
|
<title><type>jsonb</> Input and Output Syntax</title>
|
||||||
|
<para>
|
||||||
|
The input/output syntax for the JSON data types is as specified in
|
||||||
|
<acronym>RFC</> 7159.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The following are all valid <type>json</> (or <type>jsonb</>) expressions:
|
||||||
|
<programlisting>
|
||||||
|
-- Simple scalar/primitive value (explicitly required by RFC-7159)
|
||||||
|
SELECT '5'::json;
|
||||||
|
|
||||||
|
-- Array of heterogeneous, primitive-typed elements
|
||||||
|
SELECT '[1, 2, "foo", null]'::json;
|
||||||
|
|
||||||
|
-- Object of heterogeneous key/value pairs of primitive types
|
||||||
|
-- Note that key values are always strings
|
||||||
|
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Note the distinction between scalar/primitive values as array elements,
|
||||||
|
keys and values.
|
||||||
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="json-querying">
|
<sect2 id="json-querying">
|
||||||
@ -144,46 +174,19 @@
|
|||||||
summarize a set of <quote>documents</> (datums) in a table.
|
summarize a set of <quote>documents</> (datums) in a table.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<type>jsonb</> data is subject to the same concurrency control
|
<type>json</> data is subject to the same concurrency control
|
||||||
considerations as any other datatype when stored in a table.
|
considerations as any other datatype when stored in a table.
|
||||||
Although storing large documents is practicable, in order to ensure
|
Although storing large documents is practicable, in order to ensure
|
||||||
correct behavior row-level locks are, quite naturally, acquired as
|
correct behavior row-level locks are, quite naturally, acquired as
|
||||||
rows are updated. Consider keeping <type>jsonb</> documents at a
|
rows are updated. Consider keeping <type>json</> documents at a
|
||||||
manageable size in order to decrease lock contention among updating
|
manageable size in order to decrease lock contention among updating
|
||||||
transactions. Ideally, <type>jsonb</> documents should each
|
transactions. Ideally, <type>json</> documents should each
|
||||||
represent an atomic datum that business rules dictate cannot
|
represent an atomic datum that business rules dictate cannot
|
||||||
reasonably be further subdivided into smaller atomic datums that
|
reasonably be further subdivided into smaller atomic datums that
|
||||||
can be independently modified.
|
can be independently modified.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
<sect2 id="json-keys-elements">
|
|
||||||
<title><type>jsonb</> Input and Output Syntax</title>
|
|
||||||
<para>
|
|
||||||
In effect, <type>jsonb</> has an internal type system whose
|
|
||||||
implementation is defined in terms of several particular ordinary
|
|
||||||
<productname>PostgreSQL</productname> types. The SQL parser does
|
|
||||||
not have direct knowledge of the internal types that constitute a
|
|
||||||
<type>jsonb</>.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The following are all valid <type>jsonb</> expressions:
|
|
||||||
<programlisting>
|
|
||||||
-- Simple scalar/primitive value (explicitly required by RFC-7159)
|
|
||||||
SELECT '5'::jsonb;
|
|
||||||
|
|
||||||
-- Array of heterogeneous, primitive-typed elements
|
|
||||||
SELECT '[1, 2, "foo", null]'::jsonb;
|
|
||||||
|
|
||||||
-- Object of heterogeneous key/value pairs of primitive types
|
|
||||||
-- Note that key values are always strings
|
|
||||||
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Note the distinction between scalar/primitive values as elements,
|
|
||||||
keys and values.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="json-containment">
|
<sect2 id="json-containment">
|
||||||
<title><type>jsonb</> containment</title>
|
<title><type>jsonb</> containment</title>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@ -199,7 +202,7 @@ SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
|
|||||||
technically, top-down, unordered <emphasis>subtree isomorphism</>
|
technically, top-down, unordered <emphasis>subtree isomorphism</>
|
||||||
may be tested. Containment is conventionally tested using the
|
may be tested. Containment is conventionally tested using the
|
||||||
<literal>@></> operator, which is made indexable by various
|
<literal>@></> operator, which is made indexable by various
|
||||||
operator classes discussed later in this section.
|
operator classes discussed below.
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
-- Simple scalar/primitive values may contain only each other:
|
-- Simple scalar/primitive values may contain only each other:
|
||||||
@ -249,45 +252,47 @@ SELECT '{"p":1, "a":{"b":3, "q":11}, "i":77}'::jsonb @> '{"a":{"b":3}}'::jsonb;
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
The various containment operators, along with all other JSON
|
The various containment operators, along with all other JSON
|
||||||
operators and support functions are documented fully within <xref
|
operators and support functions are documented in <xref
|
||||||
linkend="functions-json">, <xref
|
linkend="functions-json">.
|
||||||
linkend="functions-jsonb-op-table">.
|
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="json-indexing">
|
<sect2 id="json-indexing">
|
||||||
<title><type>jsonb</> GIN Indexing</title>
|
<title><type>jsonb</> Indexing</title>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>jsonb</primary>
|
<primary>jsonb</primary>
|
||||||
<secondary>indexes on</secondary>
|
<secondary>indexes on</secondary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
<para>
|
|
||||||
<type>jsonb</> GIN indexes can be used to efficiently search among
|
|
||||||
more than one possible key/value pair within a single
|
|
||||||
<type>jsonb</> datum/document, among a large number of such
|
|
||||||
documents within a column in a table (i.e. among many rows).
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<type>jsonb</> has GIN index support for the <literal>@></>,
|
|
||||||
<literal>?</>, <literal>?&</> and <literal>?|</> operators.
|
|
||||||
The default GIN operator class makes all these operators
|
|
||||||
indexable:
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
-- GIN index (default opclass)
|
|
||||||
CREATE INDEX idxgin ON api USING GIN (jdoc);
|
|
||||||
|
|
||||||
-- GIN jsonb_hash_ops index
|
|
||||||
CREATE INDEX idxginh ON api USING GIN (jdoc jsonb_hash_ops);
|
|
||||||
</programlisting>
|
|
||||||
<para>
|
<para>
|
||||||
|
<type>jsonb</> GIN indexes can be used to efficiently search for
|
||||||
|
keys or key/value pairs occurring within a large number of
|
||||||
|
<type>jsonb</> documents (datums).
|
||||||
|
Two GIN <quote>operator classes</> are provided, offering different
|
||||||
|
performance and flexibility tradeoffs.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The default GIN operator class supports queries with the
|
||||||
|
<literal>@></>, <literal>?</>, <literal>?&</> and <literal>?|</>
|
||||||
|
operators.
|
||||||
|
(For details of the semantics that these operators
|
||||||
|
implement, see <xref linkend="functions-jsonb-op-table">.)
|
||||||
|
An example of creating an index with this operator class is:
|
||||||
|
<programlisting>
|
||||||
|
CREATE INDEX idxgin ON api USING gin (jdoc);
|
||||||
|
</programlisting>
|
||||||
The non-default GIN operator class <literal>jsonb_hash_ops</>
|
The non-default GIN operator class <literal>jsonb_hash_ops</>
|
||||||
supports indexing the <literal>@></> operator only.
|
supports indexing the <literal>@></> operator only.
|
||||||
|
An example of creating an index with this operator class is:
|
||||||
|
<programlisting>
|
||||||
|
CREATE INDEX idxginh ON api USING gin (jdoc jsonb_hash_ops);
|
||||||
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Consider the example of a table that stores JSON documents
|
Consider the example of a table that stores JSON documents
|
||||||
retrieved from a third-party web service, with a documented schema
|
retrieved from a third-party web service, with a documented schema
|
||||||
definition. An example of a document retrieved from this web
|
definition. A typical document is:
|
||||||
service is as follows:
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{
|
{
|
||||||
"guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
|
"guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
|
||||||
@ -305,85 +310,67 @@ CREATE INDEX idxginh ON api USING GIN (jdoc jsonb_hash_ops);
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
If a GIN index is created on the table that stores these
|
We store these documents in a table named <structname>api</>,
|
||||||
documents, <literal>api</literal>, on its <literal>jdoc</>
|
in a <type>jsonb</> column named <structfield>jdoc</>.
|
||||||
<type>jsonb</> column, we can expect that queries like the
|
If a GIN index is created on this column,
|
||||||
following may make use of the index:
|
queries like the following can make use of the index:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
-- Note that both key and value have been specified
|
-- Note that both key and value have been specified
|
||||||
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
|
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
However, the index could not be used for queries like the
|
However, the index could not be used for queries like the
|
||||||
following, due to the aforementioned nesting restriction:
|
following, because though the operator <literal>?</> is indexable,
|
||||||
|
it is not applied directly to the indexed column <structfield>jdoc</>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
|
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Still, with judicious use of expressional indexing, the above
|
Still, with judicious use of expression indexes, the above
|
||||||
query can use an index scan. If there is a requirement to find
|
query can use an index scan. If there is a requirement to find
|
||||||
those records with a particular tag quickly, and the tags have a
|
those records with a particular tag quickly, and the tags have a
|
||||||
high cardinality across all documents, defining an index as
|
high cardinality across all documents, defining an index as
|
||||||
follows is an effective approach to indexing:
|
follows is an effective approach to indexing:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
-- Note that the "jsonb -> text" operator can only be called on an
|
-- Note that the "jsonb -> text" operator can only be called on an
|
||||||
-- object, so as a consequence of creating this index the root "jdoc"
|
-- object, so as a consequence of creating this index the root of each
|
||||||
-- datum must be an object. This is enforced during insertion.
|
-- "jdoc" value must be an object. This is enforced during insertion.
|
||||||
CREATE INDEX idxgin ON api USING GIN ((jdoc -> 'tags'));
|
CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
Now, the <literal>WHERE</> clause <literal>jdoc -> 'tags' ? 'qui'</>
|
||||||
|
will be recognized as an application of the indexable
|
||||||
|
operator <literal>?</> to the indexed
|
||||||
|
expression <literal>jdoc -> 'tags'</>.
|
||||||
|
(More information on expression indexes can be found in <xref
|
||||||
|
linkend="indexes-expressional">.)
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Expressional indexes are discussed in <xref
|
Another approach to querying is to exploit containment, for example:
|
||||||
linkend="indexes-expressional">.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
For the most flexible approach in terms of what may be indexed,
|
|
||||||
sophisticated querying on nested structures is possible by
|
|
||||||
exploiting containment. At the cost of having to create an index
|
|
||||||
on the entire structure for each row, and not just a nested
|
|
||||||
subset, we may exploit containment semantics to get an equivalent
|
|
||||||
result with a non-expressional index on the entire <quote>jdoc</>
|
|
||||||
column, <emphasis>without</> ever having to create additional
|
|
||||||
expressional indexes against the document (provided only
|
|
||||||
containment will be tested). While the index will be considerably
|
|
||||||
larger than our expression index, it will also be much more
|
|
||||||
flexible, allowing arbitrary structured searching. Such an index
|
|
||||||
can generally be expected to help with a query like the following:
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
|
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
This approach uses a single GIN index covering everything in the
|
||||||
For full details of the semantics that these indexable operators
|
<literal>jdoc</> column, whereas our expression index stored only
|
||||||
implement, see <xref linkend="functions-json">, <xref
|
data found under the <literal>tags</> key. While the single-index
|
||||||
linkend="functions-jsonb-op-table">.
|
approach is certainly more flexible, targeted expression indexes
|
||||||
|
are likely to be smaller and faster to search than a single index.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
|
||||||
<sect2 id="json-opclass">
|
|
||||||
<title><type>jsonb</> non-default GIN operator class</title>
|
|
||||||
<indexterm>
|
|
||||||
<primary>jsonb</primary>
|
|
||||||
<secondary>indexes on</secondary>
|
|
||||||
</indexterm>
|
|
||||||
<para>
|
<para>
|
||||||
Although only the <literal>@></> operator is made indexable, a
|
Although the <literal>jsonb_hash_ops</literal> operator class supports
|
||||||
<literal>jsonb_hash_ops</literal> operator class GIN index has
|
only queries with the <literal>@></> operator, it has notable
|
||||||
some notable advantages over an equivalent GIN index of the
|
performance advantages over the default operator
|
||||||
default GIN operator class for <type>jsonb</type>. Search
|
class <literal>jsonb_ops</literal>. A <literal>jsonb_hash_ops</literal>
|
||||||
operations typically perform considerably better, and the on-disk
|
GIN index is usually much smaller than a <literal>jsonb_ops</literal>
|
||||||
size of a <literal>jsonb_hash_ops</literal> operator class GIN
|
index over the same data, and the specificity of searches is better,
|
||||||
index can be much smaller.
|
particularly when queries contain tags that appear frequently in the
|
||||||
|
data. Therefore search operations typically perform considerably better
|
||||||
|
than with the default operator class.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
|
||||||
<sect2 id="json-btree-indexing">
|
|
||||||
<title><type>jsonb</> B-Tree and hash indexing</title>
|
|
||||||
<para>
|
<para>
|
||||||
<type>jsonb</type> comparisons and related operations are
|
<type>jsonb</> also supports <literal>btree</> and <literal>hash</>
|
||||||
<emphasis>type-wise</>, in that the underlying
|
indexes. These are usually useful only if it's important to check
|
||||||
<productname>PostgreSQL</productname> datatype comparators are
|
equality of complete JSON documents.
|
||||||
invoked recursively, much like a traditional composite type.
|
The <literal>btree</> ordering for <type>jsonb</> datums is:
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<type>jsonb</> also supports <type>btree</> and <type>hash</>
|
|
||||||
indexes. Ordering between <type>jsonb</> datums is:
|
|
||||||
<synopsis>
|
<synopsis>
|
||||||
<replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
|
<replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
|
||||||
|
|
||||||
@ -391,23 +378,24 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
|
|||||||
|
|
||||||
<replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
|
<replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
Subsequently, individual primitive type comparators are invoked.
|
Objects with equal numbers of pairs are compared in the order:
|
||||||
All comparisons of JSON primitive types occurs using the same
|
|
||||||
comparison rules as the underlying
|
|
||||||
<productname>PostgreSQL</productname> types. Strings are
|
|
||||||
compared lexically, using the default database collation.
|
|
||||||
Objects with equal numbers of pairs are compared:
|
|
||||||
<synopsis>
|
<synopsis>
|
||||||
<replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
|
<replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
|
||||||
</synopsis>
|
</synopsis>
|
||||||
Note however that object keys are compared in their storage order, and in particular,
|
Note however that object keys are compared in their storage order, and
|
||||||
since shorter keys are stored before longer keys, this can lead to results that might be
|
in particular, since shorter keys are stored before longer keys, this
|
||||||
unintuitive, such as:
|
can lead to results that might be unintuitive, such as:
|
||||||
<programlisting>{ "aa": 1, "c": 1} > {"b": 1, "d": 1}</programlisting>
|
<programlisting>
|
||||||
|
{ "aa": 1, "c": 1} > {"b": 1, "d": 1}
|
||||||
|
</programlisting>
|
||||||
Similarly, arrays with equal numbers of elements are compared:
|
Similarly, arrays with equal numbers of elements are compared:
|
||||||
<synopsis>
|
<synopsis>
|
||||||
<replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
|
<replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
|
||||||
</synopsis>
|
</synopsis>
|
||||||
|
Primitive JSON values are compared using the same
|
||||||
|
comparison rules as for the underlying
|
||||||
|
<productname>PostgreSQL</productname> data type. Strings are
|
||||||
|
compared using the default database collation.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
@ -3618,14 +3618,14 @@ ALTER EXTENSION hstore UPDATE;
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Allow <type>JSON</> values to be <link
|
Allow <type>JSON</> values to be <link
|
||||||
linkend="functions-json-table">converted into records</link>
|
linkend="functions-json">converted into records</link>
|
||||||
(Andrew Dunstan)
|
(Andrew Dunstan)
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Add <link linkend="functions-json-table">functions</link> to convert
|
Add <link linkend="functions-json">functions</link> to convert
|
||||||
scalars, records, and <type>hstore</> values to <type>JSON</> (Andrew
|
scalars, records, and <type>hstore</> values to <type>JSON</> (Andrew
|
||||||
Dunstan)
|
Dunstan)
|
||||||
</para>
|
</para>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user