Thread: Are we sufficiently clear that jsonb containment is nested?

Are we sufficiently clear that jsonb containment is nested?

From
Peter Geoghegan
Date:
I worry that "8.14.3. jsonb Containment and Existence" is not
sufficiently clear in explaining that jsonb containment is nested.
I've seen anecdata suggesting that this is unclear to users. We do
say:

"""
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.
"""

I think that we could still do with an example showing *nested*
containment, where many non-matching elements/pairs at each of several
nesting levels are discarded. This could be back-patched to 9.4.
Something roughly like the delicious sample data, where queries like
the following are possible and useful:

postgres=# select jsonb_pretty(doc) from delicious where doc @>
'{"tags":[{"term":"Florence" }, {"term":"food"} ]  }' limit 1;
jsonb_pretty
-----------------------------------------------------------------------------------------------------------------{
                                 +    "id": "http://delicious.com/url/5f05d61a6e8519e9c9c8c557216375da#Avrami",
                      +    "link":
"http://www.foodnetwork.com/recipes/tyler-florence/the-ultimate-lasagna-recipe/index.html",     +    "tags": [
                             +        {                                        +            "term": "Lasagna",
                             +            "label": null,                                        +            "scheme":
"http://delicious.com/Avrami/"                                       +        },
+
*** SNIP ***                                   +    "title": "The Ultimate Lasagna Recipe : Tyler Florence : Food
Network",                                    +    "author": "Avrami",                                        +
"source":{                                        +    },                                        +    "updated": "Fri,
11Sep 2009 17:09:20 +0000",                                        +    "comments":
 
"http://delicious.com/url/5f05d61a6e8519e9c9c8c557216375da",                       +    "guidislink": false,
                           +    "title_detail": {                                        +        "base":
 
"http://feeds.delicious.com/v2/rss/recent?min=1&count=100",                       +        "type": "text/plain",
                               +        "value": "The Ultimate Lasagna Recipe : Tyler Florence : Food
 
Network",                                +        "language": null                                        +    },
                                +    "wfw_commentrss":
 
"http://feeds.delicious.com/v2/rss/url/5f05d61a6e8519e9c9c8c557216375da"               +}
(1 row)

Obviously a real doc-patch example would have to be more worked out
and clearer than what I show here. My immediate concern is whether
users appreciate that jsonb is capable of this kind of complex, nested
containment-driven querying. I do not recall ever seeing an example
like this in the wild, which is where this concern comes from. It
would be a shame if they were working around a non-existent
limitation, especially given that this kind of thing can work
reasonably effectively with the jsonb_path_ops opclass.

Opinions?
-- 
Peter Geoghegan



Re: Are we sufficiently clear that jsonb containment is nested?

From
Robert Haas
Date:
On Wed, Jun 24, 2015 at 5:53 PM, Peter Geoghegan <pg@heroku.com> wrote:
> I worry that "8.14.3. jsonb Containment and Existence" is not
> sufficiently clear in explaining that jsonb containment is nested.
> I've seen anecdata suggesting that this is unclear to users. We do
> say:
>
> """
> 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.
> """
>
> I think that we could still do with an example showing *nested*
> containment, where many non-matching elements/pairs at each of several
> nesting levels are discarded. This could be back-patched to 9.4.
> Something roughly like the delicious sample data, where queries like
> the following are possible and useful:

I would be fine with adding a *compact* example of this kind to the
table that begins section 8.14.3.  I probably would not back-patch it,
because the absence of that example is not an error in the
documentation, but I will not complain if someone else does.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: Are we sufficiently clear that jsonb containment is nested?

From
Peter Geoghegan
Date:
On Fri, Jun 26, 2015 at 8:05 AM, Robert Haas <robertmhaas@gmail.com> wrote:
> I would be fine with adding a *compact* example of this kind to the
> table that begins section 8.14.3.  I probably would not back-patch it,
> because the absence of that example is not an error in the
> documentation, but I will not complain if someone else does.

How about the attached? It's a compact refinement of my original
example of more complicated jsonb containment.

I still think it would be a good idea to go back to 9.4. I have reason
to believe that people are getting confused on this point.

--
Peter Geoghegan

Attachment

Re: Are we sufficiently clear that jsonb containment is nested?

From
Tom Lane
Date:
Peter Geoghegan <pg@heroku.com> writes:
> On Fri, Jun 26, 2015 at 8:05 AM, Robert Haas <robertmhaas@gmail.com> wrote:
>> I would be fine with adding a *compact* example of this kind to the
>> table that begins section 8.14.3.  I probably would not back-patch it,
>> because the absence of that example is not an error in the
>> documentation, but I will not complain if someone else does.

> How about the attached? It's a compact refinement of my original
> example of more complicated jsonb containment.

You seem to have injected unrelated text into the middle of a discussion.
I think what you added is fine, but not where you put it; it would make
more sense as a standalone para.

I think the existing text is largely my fault, so I'll do something with
this.

> I still think it would be a good idea to go back to 9.4. I have reason
> to believe that people are getting confused on this point.

You didn't present evidence backing that up, but I agree that
clarification is a sufficient reason to back-patch doc changes.
        regards, tom lane



Re: Are we sufficiently clear that jsonb containment is nested?

From
Peter Geoghegan
Date:
On Thu, Oct 29, 2015 at 1:16 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> I think the existing text is largely my fault, so I'll do something with
> this.

Good. Thanks.

>> I still think it would be a good idea to go back to 9.4. I have reason
>> to believe that people are getting confused on this point.
>
> You didn't present evidence backing that up, but I agree that
> clarification is a sufficient reason to back-patch doc changes.

It's difficult to provide evidence for the existence of a perception
among users when it's a perception that a quasi-reasonable limitation
exists. The fact that jsonb_path_ops can make indexing complex jsonb
documents practical is fairly novel, so I'm not surprised that users
seem to imagine that containment does not work in a nested fashion.
"Existence" (the ? operator) actually has this limitation.

-- 
Peter Geoghegan



Re: Are we sufficiently clear that jsonb containment is nested?

From
Tom Lane
Date:
Peter Geoghegan <pg@heroku.com> writes:
> On Thu, Oct 29, 2015 at 1:16 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> I think the existing text is largely my fault, so I'll do something with
>> this.

> Good. Thanks.

After studying the proposed patch a bit more, I still think the example
is good, but the added text doesn't do much to explain your point.  If
I get what your point is, which maybe I don't, I think the attached might
clarify it better.  What do you think of this version?

            regards, tom lane

diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml
index 118fb35..b2efc80 100644
*** a/doc/src/sgml/json.sgml
--- b/doc/src/sgml/json.sgml
*************** SELECT '"bar"'::jsonb @> '["bar"]'::j
*** 319,324 ****
--- 319,346 ----
  </programlisting>

    <para>
+    Keep in mind that containment is <emphasis>nested</>; an appropriate
+    query can skip explicit selection of sub-objects.  As an example, suppose
+    that our <structfield>doc</> column contains objects at the top level,
+    with all or most objects containing <literal>tags</> fields that contain
+    arrays of sub-objects.  This query finds entries in which sub-objects
+    containing both <literal>"term":"paris"</> and <literal>"term":"food"</>
+    appear, ignoring any cases where such keys appear outside
+    the <literal>tags</> array:
+ <programlisting>
+ -- Return "site_name" where at least the terms "paris" and "food" appear:
+ SELECT doc->'site_name' FROM websites
+   WHERE doc @> '{"tags":[{"term":"paris"}, {"term":"food"}]}';
+ </programlisting>
+    One could accomplish the same thing with, say,
+ <programlisting>
+ SELECT doc->'site_name' FROM websites
+   WHERE doc->'tags' @> '[{"term":"paris"}, {"term":"food"}]';
+ </programlisting>
+    but that approach is less flexible, and often less efficient as well.
+   </para>
+
+   <para>
      <type>jsonb</> also has an <firstterm>existence</> operator, which is
      a variation on the theme of containment: it tests whether a string
      (given as a <type>text</> value) appears as an object key or array

Re: Are we sufficiently clear that jsonb containment is nested?

From
Peter Geoghegan
Date:
On Thu, Oct 29, 2015 at 2:02 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> After studying the proposed patch a bit more, I still think the example
> is good, but the added text doesn't do much to explain your point.  If
> I get what your point is, which maybe I don't, I think the attached might
> clarify it better.  What do you think of this version?

Robert seemed to want to keep the example short, which I took on
board, but I myself think that your more worked out treatment is
better. I think this revision makes my point very well. I recommend
committing it.

-- 
Peter Geoghegan



Re: Are we sufficiently clear that jsonb containment is nested?

From
Tom Lane
Date:
Peter Geoghegan <pg@heroku.com> writes:
> Robert seemed to want to keep the example short, which I took on
> board, but I myself think that your more worked out treatment is
> better. I think this revision makes my point very well. I recommend
> committing it.

After further thought I realized that part of the point you'd been
making was that people might fail to distinguish the behaviors of
containment and existence operators in this regard.  So I think the
example needs to make that point explicitly.  I whacked it around
a bit more and committed it.
        regards, tom lane



Re: Are we sufficiently clear that jsonb containment is nested?

From
Peter Geoghegan
Date:
On Thu, Oct 29, 2015 at 4:03 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> After further thought I realized that part of the point you'd been
> making was that people might fail to distinguish the behaviors of
> containment and existence operators in this regard.  So I think the
> example needs to make that point explicitly.  I whacked it around
> a bit more and committed it.

Looks good.

-- 
Peter Geoghegan