Improve user-facing JSON documentation.
authorTom Lane
Fri, 9 May 2014 20:33:25 +0000 (16:33 -0400)
committerTom Lane
Fri, 9 May 2014 20:33:25 +0000 (16:33 -0400)
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.

doc/src/sgml/func.sgml
doc/src/sgml/gin.sgml
doc/src/sgml/json.sgml
doc/src/sgml/release-9.3.sgml

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