diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index affd1254bb..295f8ca5c9 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17205,7 +17205,7 @@ array w/o UK? | t
For example, suppose you have some JSON data from a GPS tracker that you
would like to parse, such as:
-{
+ \set json '{
"track": {
"segments": [
{
@@ -17220,7 +17220,7 @@ array w/o UK? | t
}
]
}
-}
+}'
@@ -17229,7 +17229,10 @@ array w/o UK? | t
.key accessor
operator to descend through surrounding JSON objects:
-$.track.segments
+select jsonb_path_query(:'json'::jsonb, '$.track.segments');
+ jsonb_path_query
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [{"HR": 73, "location": [47.763, 13.4034], "start time": "2018-10-14 10:05:14"}, {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}]
@@ -17239,7 +17242,11 @@ $.track.segments
the following path will return the location coordinates for all
the available track segments:
-$.track.segments[*].location
+select jsonb_path_query(:'json'::jsonb, '$.track.segments[*].location');
+ jsonb_path_query
+-------------------
+ [47.763, 13.4034]
+ [47.706, 13.2635]
@@ -17248,7 +17255,10 @@ $.track.segments[*].location
specify the corresponding subscript in the []
accessor operator. Recall that JSON array indexes are 0-relative:
-$.track.segments[0].location
+select jsonb_path_query(:'json'::jsonb, 'strict $.track.segments[0].location');
+ jsonb_path_query
+-------------------
+ [47.763, 13.4034]
@@ -17259,7 +17269,10 @@ $.track.segments[0].location
Each method name must be preceded by a dot. For example,
you can get the size of an array:
-$.track.segments.size()
+select jsonb_path_query(:'json'::jsonb, 'strict $.track.segments.size()');
+ jsonb_path_query
+------------------
+ 2
More examples of using jsonpath operators
and methods within path expressions appear below in
@@ -17302,7 +17315,10 @@ $.track.segments.size()
For example, suppose you would like to retrieve all heart rate values higher
than 130. You can achieve this using the following expression:
-$.track.segments[*].HR ? (@ > 130)
+select jsonb_path_query(:'json'::jsonb, '$.track.segments[*].HR ? (@ > 130)');
+ jsonb_path_query
+------------------
+ 135
@@ -17312,7 +17328,10 @@ $.track.segments[*].HR ? (@ > 130)
filter expression is applied to the previous step, and the path used
in the condition is different:
-$.track.segments[*] ? (@.HR > 130)."start time"
+ select jsonb_path_query(:'json'::jsonb, '$.track.segments[*] ? (@.HR > 130)."start time"');
+ jsonb_path_query
+-----------------------
+ "2018-10-14 10:39:21"
@@ -17321,7 +17340,10 @@ $.track.segments[*] ? (@.HR > 130)."start time"
example, the following expression selects start times of all segments that
contain locations with relevant coordinates and high heart rate values:
-$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"
+select jsonb_path_query(:'json'::jsonb, '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"');
+ jsonb_path_query
+-----------------------
+ "2018-10-14 10:39:21"
@@ -17330,46 +17352,81 @@ $.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"
The following example first filters all segments by location, and then
returns high heart rate values for these segments, if available:
-$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)
+select jsonb_path_query(:'json'::jsonb, $.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)');
+ jsonb_path_query
+------------------
+ 135
You can also nest filter expressions within each other:
-$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()
+select jsonb_path_query(:'json'::jsonb, $.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()');
+ jsonb_path_query
+------------------
+ 2
This expression returns the size of the track if it contains any
segments with high heart rate values, or an empty sequence otherwise.
-
- PostgreSQL's implementation of the SQL/JSON path
- language has the following deviations from the SQL/JSON standard:
-
+
+ Devaiations from the SQL Standard
+
+ PostgreSQL's implementation of the SQL/JSON path
+ language has the following deviations from the SQL/JSON standard:
+
-
-
+
+ Boolean Predicate Path Expressions
- A path expression can be a Boolean predicate, although the SQL/JSON
- standard allows predicates only in filters. This is necessary for
- implementation of the @@ operator. For example,
- the following jsonpath expression is valid in
- PostgreSQL:
+ As an extension to the SQL standard, a PostgreSQL
+ path expression can be a Boolean predicate, whereas the SQL standard allows
+ predicates only in filters. Where SQL standard path expressions return the
+ relevant contents of the queried JSON value, predicate path expressions
+ return the three-value three-valued result of the predicate:
+ true, false, or
+ unknown. Compare this filter jsonpath
+ exression:
-$.track.segments[*].HR < 70
+select jsonb_path_query(:'json'::jsonb, '$.track.segments ?(@[*].HR > 130)');
+ jsonb_path_query
+---------------------------------------------------------------------------------
+ {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}
-
-
+ To a predicate expression, which returns true
+
+select jsonb_path_query(:'json'::jsonb, '$.track.segments[*].HR > 130');
+ jsonb_path_query
+------------------
+ true
+
+
-
-
- There are minor differences in the interpretation of regular
- expression patterns used in like_regex filters, as
- described in .
-
-
-
+
+ Predicate-only path expressions are necessary for implementation of the
+ @@ operator (and the
+ jsonb_path_match function), and should not be used
+ with the @? operator (or
+ jsonb_path_exists function).
+
+
+
+ Conversely, non-predicate jsonpath expressions should not be
+ used with the @@ operator (or the
+ jsonb_path_match function).
+
+
+
+
+ Regular Expression Interpretation
+
+ There are minor differences in the interpretation of regular
+ expression patterns used in like_regex filters, as
+ described in .
+
+
Strict and Lax Modes
@@ -17431,18 +17488,30 @@ $.track.segments[*].HR < 70
abstract from the fact that it stores an array of segments
when using the lax mode:
-lax $.track.segments.location
+ select jsonb_path_query(:'json'::jsonb, 'lax $.track.segments.location');
+ jsonb_path_query
+-------------------
+ [47.763, 13.4034]
+ [47.706, 13.2635]
- In the strict mode, the specified path must exactly match the structure of
+ In strict mode, the specified path must exactly match the structure of
the queried JSON document to return an SQL/JSON item, so using this
- path expression will cause an error. To get the same result as in
- the lax mode, you have to explicitly unwrap the
+ path expression will cause an error:
+
+select jsonb_path_query(:'json'::jsonb, 'strict $.track.segments.location');
+ERROR: jsonpath member accessor can only be applied to an object
+
+ To get the same result as in the lax mode, you have to explicitly unwrap the
segments array:
-strict $.track.segments[*].location
+select jsonb_path_query(:'json'::jsonb, 'strict $.track.segments[*].location');
+ jsonb_path_query
+-------------------
+ [47.763, 13.4034]
+ [47.706, 13.2635]
@@ -17451,7 +17520,13 @@ strict $.track.segments[*].location
when using the lax mode. For instance, the following query selects every
HR value twice:
-lax $.**.HR
+select jsonb_path_query(:'json'::jsonb, 'lax $.**.HR');
+ jsonb_path_query
+------------------
+ 73
+ 135
+ 73
+ 135
This happens because the .** accessor selects both
the segments array and each of its elements, while
@@ -17460,7 +17535,11 @@ lax $.**.HR
the .** accessor only in the strict mode. The
following query selects each HR value just once:
-strict $.**.HR
+select jsonb_path_query(:'json'::jsonb, 'strict $.**.HR');
+ jsonb_path_query
+------------------
+ 73
+ 135