Home Explore Blog CI



postgresql

5th chunk of `doc/src/sgml/json.sgml`
62277a19ef6919c7e5f7119c5fa21608fc59cbf47c1ebf690000000100000fa3
 <firstterm>containment</firstterm> is an important capability of
    <type>jsonb</type>.  There is no parallel set of facilities for the
    <type>json</type> type.  Containment tests whether
    one <type>jsonb</type> document has contained within it another one.
    These examples return true except as noted:
  </para>
<programlisting>
-- Simple scalar/primitive values contain only the identical value:
SELECT '"foo"'::jsonb @&gt; '"foo"'::jsonb;

-- The array on the right side is contained within the one on the left:
SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 3]'::jsonb;

-- Order of array elements is not significant, so this is also true:
SELECT '[1, 2, 3]'::jsonb @&gt; '[3, 1]'::jsonb;

-- Duplicate array elements don't matter either:
SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 2, 2]'::jsonb;

-- The object with a single pair on the right side is contained
-- within the object on the left side:
SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @&gt; '{"version": 9.4}'::jsonb;

-- The array on the right side is <emphasis>not</emphasis> considered contained within the
-- array on the left, even though a similar array is nested within it:
SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[1, 3]'::jsonb;  -- yields false

-- But with a layer of nesting, it is contained:
SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[[1, 3]]'::jsonb;

-- Similarly, containment is not reported here:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @&gt; '{"bar": "baz"}'::jsonb;  -- yields false

-- A top-level key and an empty object is contained:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @&gt; '{"foo": {}}'::jsonb;
</programlisting>

  <para>
   The general principle is that the contained object must match the
   containing object as to structure and data contents, possibly after
   discarding some non-matching array elements or object key/value pairs
   from the containing object.
   But remember that the order of array elements is not significant when
   doing a containment match, and duplicate array elements are effectively
   considered only once.
  </para>

  <para>
   As a special exception to the general principle that the structures
   must match, an array may contain a primitive value:
  </para>
<programlisting>
-- This array contains the primitive string value:
SELECT '["foo", "bar"]'::jsonb @&gt; '"bar"'::jsonb;

-- This exception is not reciprocal -- non-containment is reported here:
SELECT '"bar"'::jsonb @&gt; '["bar"]'::jsonb;  -- yields false
</programlisting>

  <para>
    <type>jsonb</type> also has an <firstterm>existence</firstterm> operator, which is
    a variation on the theme of containment: it tests whether a string
    (given as a <type>text</type> value) appears as an object key or array
    element at the top level of the <type>jsonb</type> value.
    These examples return true except as noted:
  </para>
<programlisting>
-- String exists as array element:
SELECT '["foo", "bar", "baz"]'::jsonb ? 'bar';

-- String exists as object key:
SELECT '{"foo": "bar"}'::jsonb ? 'foo';

-- Object values are not considered:
SELECT '{"foo": "bar"}'::jsonb ? 'bar';  -- yields false

-- As with containment, existence must match at the top level:
SELECT '{"foo": {"bar": "baz"}}'::jsonb ? 'bar'; -- yields false

-- A string is considered to exist if it matches a primitive JSON string:
SELECT '"foo"'::jsonb ? 'foo';
</programlisting>

  <para>
    JSON objects are better suited than arrays for testing containment or
    existence when there are many keys or elements involved, because
    unlike arrays they are internally optimized for searching, and do not
    need to be searched linearly.
  </para>

  <tip>
   <para>
    Because JSON containment is nested, an appropriate query can skip
    explicit selection of sub-objects.  As an example, suppose that we have
    a <structfield>doc</structfield> column containing objects at the top level, with
    most objects containing <literal>tags</literal> fields that contain arrays of
    sub-objects.  This query finds

Title: JSONB Containment and Existence in PostgreSQL
Summary
JSONB in PostgreSQL supports containment and existence tests, allowing users to check if one JSONB document contains another or if a specific string exists as an object key or array element, with examples demonstrating the usage of these operators and their behavior with different data types and structures.