163
163
</para>
164
164
<para>
165
165
The following are all valid <type>json</> (or <type>jsonb</>) expressions:
166
- <programlisting>
166
+ <programlisting>
167
167
-- Simple scalar/primitive value
168
168
-- Primitive values can be numbers, quoted strings, true, false, or null
169
169
SELECT '5'::json;
@@ -177,7 +177,7 @@ SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;
177
177
178
178
-- Arrays and objects can be nested arbitrarily
179
179
SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
180
- </programlisting>
180
+ </programlisting>
181
181
</para>
182
182
183
183
<para>
@@ -262,7 +262,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
262
262
one <type>jsonb</> document has contained within it another one.
263
263
These examples return true except as noted:
264
264
</para>
265
- <programlisting>
265
+ <programlisting>
266
266
-- Simple scalar/primitive values contain only the identical value:
267
267
SELECT '"foo"'::jsonb @> '"foo"'::jsonb;
268
268
@@ -282,7 +282,7 @@ SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb;
282
282
283
283
-- Similarly, containment is not reported here:
284
284
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields false
285
- </programlisting>
285
+ </programlisting>
286
286
287
287
<para>
288
288
The general principle is that the contained object must match the
@@ -296,13 +296,13 @@ SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields f
296
296
As a special exception to the general principle that the structures
297
297
must match, an array may contain a primitive value:
298
298
</para>
299
- <programlisting>
299
+ <programlisting>
300
300
-- This array contains the primitive string value:
301
301
SELECT '["foo", "bar"]'::jsonb @> '"bar"'::jsonb;
302
302
303
303
-- This exception is not reciprocal -- non-containment is reported here:
304
304
SELECT '"bar"'::jsonb @> '["bar"]'::jsonb; -- yields false
305
- </programlisting>
305
+ </programlisting>
306
306
307
307
<para>
308
308
<type>jsonb</> also has an <firstterm>existence</> operator, which is
@@ -363,22 +363,22 @@ SELECT '"foo"'::jsonb ? 'foo';
363
363
(For details of the semantics that these operators
364
364
implement, see <xref linkend="functions-jsonb-op-table">.)
365
365
An example of creating an index with this operator class is:
366
- <programlisting>
366
+ <programlisting>
367
367
CREATE INDEX idxgin ON api USING gin (jdoc);
368
- </programlisting>
368
+ </programlisting>
369
369
The non-default GIN operator class <literal>jsonb_path_ops</>
370
370
supports indexing the <literal>@></> operator only.
371
371
An example of creating an index with this operator class is:
372
- <programlisting>
372
+ <programlisting>
373
373
CREATE INDEX idxginp ON api USING gin (jdoc jsonb_path_ops);
374
- </programlisting>
374
+ </programlisting>
375
375
</para>
376
376
377
377
<para>
378
378
Consider the example of a table that stores JSON documents
379
379
retrieved from a third-party web service, with a documented schema
380
380
definition. A typical document is:
381
- <programlisting>
381
+ <programlisting>
382
382
{
383
383
"guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
384
384
"name": "Angela Barton",
@@ -394,32 +394,32 @@ CREATE INDEX idxginp ON api USING gin (jdoc jsonb_path_ops);
394
394
"qui"
395
395
]
396
396
}
397
- </programlisting>
397
+ </programlisting>
398
398
We store these documents in a table named <structname>api</>,
399
399
in a <type>jsonb</> column named <structfield>jdoc</>.
400
400
If a GIN index is created on this column,
401
401
queries like the following can make use of the index:
402
- <programlisting>
402
+ <programlisting>
403
403
-- Find documents in which the key "company" has value "Magnafone"
404
404
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
405
- </programlisting>
405
+ </programlisting>
406
406
However, the index could not be used for queries like the
407
407
following, because though the operator <literal>?</> is indexable,
408
408
it is not applied directly to the indexed column <structfield>jdoc</>:
409
- <programlisting>
409
+ <programlisting>
410
410
-- Find documents in which the key "tags" contains key or array element "qui"
411
411
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
412
- </programlisting>
412
+ </programlisting>
413
413
Still, with appropriate use of expression indexes, the above
414
414
query can use an index. If querying for particular items within
415
415
the <literal>"tags"</> key is common, defining an index like this
416
416
may be worthwhile:
417
- <programlisting>
417
+ <programlisting>
418
418
-- Note that the "jsonb -> text" operator can only be called on a JSON
419
419
-- object, so as a consequence of creating this index the root of each
420
420
-- "jdoc" value must be an object. This is enforced during insertion.
421
421
CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
422
- </programlisting>
422
+ </programlisting>
423
423
Now, the <literal>WHERE</> clause <literal>jdoc -> 'tags' ? 'qui'</>
424
424
will be recognized as an application of the indexable
425
425
operator <literal>?</> to the indexed
@@ -429,10 +429,10 @@ CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
429
429
</para>
430
430
<para>
431
431
Another approach to querying is to exploit containment, for example:
432
- <programlisting>
432
+ <programlisting>
433
433
-- Find documents in which the key "tags" contains array element "qui"
434
434
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
435
- </programlisting>
435
+ </programlisting>
436
436
A simple GIN index on the <structfield>jdoc</> column can support this
437
437
query. But note that such an index will store copies of every key and
438
438
value in the <structfield>jdoc</> column, whereas the expression index
@@ -460,7 +460,7 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
460
460
and a <literal>jsonb_path_ops</literal> GIN index is that the former
461
461
creates independent index items for each key and value in the data,
462
462
while the latter creates index items only for each value in the
463
- data.
463
+ data.
464
464
<footnote>
465
465
<para>
466
466
For this purpose, the term <quote>value</> includes array elements,
@@ -501,17 +501,17 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
501
501
equality of complete JSON documents.
502
502
The <literal>btree</> ordering for <type>jsonb</> datums is seldom
503
503
of great interest, but for completeness it is:
504
- <synopsis>
505
- <replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
504
+ <synopsis>
505
+ <replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
506
506
507
- <replaceable>Object with n pairs</replaceable> > <replaceable>object with n - 1 pairs</replaceable>
507
+ <replaceable>Object with n pairs</replaceable> > <replaceable>object with n - 1 pairs</replaceable>
508
508
509
- <replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
510
- </synopsis>
509
+ <replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
510
+ </synopsis>
511
511
Objects with equal numbers of pairs are compared in the order:
512
- <synopsis>
513
- <replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
514
- </synopsis>
512
+ <synopsis>
513
+ <replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
514
+ </synopsis>
515
515
Note that object keys are compared in their storage order;
516
516
in particular, since shorter keys are stored before longer keys, this
517
517
can lead to results that might be unintuitive, such as:
@@ -520,9 +520,9 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
520
520
</programlisting>
521
521
Similarly, arrays with equal numbers of elements are compared in the
522
522
order:
523
- <synopsis>
524
- <replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
525
- </synopsis>
523
+ <synopsis>
524
+ <replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
525
+ </synopsis>
526
526
Primitive JSON values are compared using the same
527
527
comparison rules as for the underlying
528
528
<productname>PostgreSQL</productname> data type. Strings are
0 commit comments