ietf-wg-jsonpath / draft-ietf-jsonpath-base

Development of a JSONPath internet draft
https://ietf-wg-jsonpath.github.io/draft-ietf-jsonpath-base/
Other
59 stars 20 forks source link

Should list selectors allow filter selectors? #150

Closed cabo closed 2 years ago

cabo commented 2 years ago

https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-base/pull/147#discussion_r790396618

https://cburgmer.github.io/json-path-comparison/results/union_with_filter.html

cabo commented 2 years ago

(To me it is inexplicable they aren't already. But changing that was not the remit of #147.)

goessner commented 2 years ago

I am fine with the status quo of excluding filters within list selectors.

Any striking use cases I am not aware of?

gregsdennis commented 2 years ago

As mentioned in my comment, I see no reason why a filter can't be included in a list. Some people may prefer to have multiple simple expressions for readability.

My implementation already supports this (I'll have to disable this functionality or hide it behind an option if we don't include it).

cabo commented 2 years ago

I don't have a strong opinion on this question.

But not only does it seem natural to include filter selectors in list selectors: the comparison project also shows that most implementations that do provide this, also agree on what the result should be. So this would not be a risky addition.

goessner commented 2 years ago

I do have a strong opinion here, as ...

Example above

$[?(@.key<3),?(@.key>6)]

is easily - and more consistently - reformulated as a pure filter-selector

$[?(@.key<3 || @.key>6)]

So I would like to see real use cases to be convinced here.

If filter selectors are natural to be included in list selectors, then so are

cabo commented 2 years ago

On 2022-01-24, at 16:58, Stefan Goessner @.***> wrote:

@.**@.>6)]

is easily - and more consistently - reformulated as a pure filter-selector

@.***<3 || @.key>6)]

(The sequence of data items is different between the two.)

So I would like to see real use cases to be convinced here.

If filter selectors are natural to be included in list selectors, then so are

• index-wild-selector

Could be done.

• descendant-selector

There is no natural syntax for that.

• and even list-selector

That already works :-)

If you have the list selector [1, 2, 3], you can include that in [4, 5, 6] by unpacking the brackets, so you have 1, 2, 3, and appending that to the comma-separated list, so you have [4, 5, 6, 1, 2, 3]

(Note that all the embedded selectors have their brackets removed before including them in a list-selector.)

Grüße, Carsten

goessner commented 2 years ago

(The sequence of data items is different between the two.)

???

That already works :-) If you have the list selector [1, 2, 3], you can include that in [4, 5, 6] by unpacking the brackets, so you have 1, 2, 3, and appending that to the comma-separated list, so you have [4, 5, 6, 1, 2, 3]

:-)

(Note that all the embedded selectors have their brackets removed before including them in a list-selector.)

... even with filter selectors ?

cabo commented 2 years ago

On 2022-01-24, at 17:34, Stefan Goessner @.***> wrote:

(The sequence of data items is different between the two.)

???

A list selector selects the nodes that are selected by at least one of the selector entries in the list and yields the concatenation of the lists (in the order of the selector entries) of nodes selected by the selector entries.

(I just pushed a slight editorial fix that distinguishes between selectors in general and selector entries in a list selector — the latter don’t have the brackets.)

Note the "(in the order of the selector entries)”.

So applying $[?(@ % 2 == 0), ?(@ % 2 != 0)] to [1, 2, 3, 4] yields

2, 4, 1, 3

…while applying $[?(@ % 2 == 0 || @ % 2 != 0)] to [1, 2, 3, 4] yields

1, 2, 3, 4

(Note that all the embedded selectors have their brackets removed before including them in a list-selector.)

... even with filter selectors ?

Yes, putting [?(@ % 2 == 0)] and [?(@ % 2 != 0)] into a list selector yields [?(@ % 2 == 0), ?(@ % 2 != 0)]. The brackets of the individual filter selectors are gone.

Grüße, Carsten

glyn commented 2 years ago

My preference is to include filter selectors in list selectors simply because omitting them seems arbitrary and rather surprising.

I don't have a use case to justify this, although I could probably fabricate one if pushed. ;-)

gregsdennis commented 2 years ago

I think the key to the utility here is mixing selector types. If the user wanted to get the first item and also any item where @.key == "foo", then they can do:

$[1,?(@.key=="foo")]

To my knowledge, this can't be done in a single expression.

goessner commented 2 years ago
$[1,?(@.key=="foo")]

To my knowledge, this can't be done in a single expression.

... this is true ...

goessner commented 2 years ago

So applying $[?(@ % 2 == 0), ?(@ % 2 != 0)] to [1, 2, 3, 4] yields 2, 4, 1, 3 …

I think you are aware of using arithmethic operators here.

JSONPath is for selection exclusively. JSONPath is not for calculation.

danielaparker commented 2 years ago

So applying $[?(@ % 2 == 0), ?(@ % 2 != 0)] to [1, 2, 3, 4] yields 2, 4, 1, 3 …

I think you are aware of using arithmetic operators here.

JSONPath is for selection exclusively. JSONPath is not for calculation.

Selection and calculation are not mutually exclusive, though. Consider

[
  {"product":"A", "price":10, "quantity":10},   
  {"product":"B", "price":10, "quantity":1000}   
]

$[?(@.price*@.quantity >= 10000)].product

Javascript Goessner returns

["B"]
goessner commented 2 years ago

I do know this very well ... since I am pragmatically reusing the javascript engine for evaluation.

People then would want to know/apply ...

Even when restricting to basic arithmetic operations we need to handle division by zero, NaN, equality of floats/doubles, truncation, rounding, ...

Your example above can be solved with a three-liner ... or by smart post-processing of JSONPath selection results.

JSONPath is for selection ... the right tool for the right task.

danielaparker commented 2 years ago

@goessner

JSONPath is for selection ... the right tool for the right task.

I think it all comes down to taste. The taste of the language designer.

With regards to prior experience, there are query languages that have arithmetic operations (SQL, XPath, JSONiq, all JSONPath implementations that use Javascript, Python, Lua) and others that do not (JMESPath, Jayway JSONPath). Either way, there is plenty of prior experience to draw on. There are answers to the technical questions. But taste is another matter.

Best regards, Daniel

gregsdennis commented 2 years ago

I think we're getting a little of topic here. We want to know if there are use cases for including the ?(...) syntax as a viable member of a list selector.

I think my example shows that there is a use case, even if somewhat constructed. Someone is going to try it.

danielaparker commented 2 years ago

I think we're getting a little of topic here. We want to know if there are use cases for including the ?(...) syntax as a viable member of a list selector.

There may be uses cases, but does it even matter? The main argument for allowing filter selectors, indeed all selectors, in the "list selector" is that it removes special cases, simplifies the grammar, presents no difficulties for implementations, and affords the user some additional flexibility. I think the same arguments apply to allowing the wildcard selector, although I can't think of any use cases that would benefit from that.

glyn commented 2 years ago

That's my position too Daniel.

On Wed, 26 Jan 2022, 13:36 Daniel Parker, @.***> wrote:

I think we're getting a little of topic here. We want to know if there are use cases for including the ?(...) syntax as a viable member of a list selector.

There may be uses cases, but does it even matter? The main argument for allowing filter selectors, indeed all selectors, in the "list selector" is that it removes special cases, simplifies the grammar, presents no difficulties for implementations, and affords the user some additional flexibility. I think the same arguments apply to allowing the wildcard selector, although I can't think of any use cases that would benefit from that.

— Reply to this email directly, view it on GitHub https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-base/issues/150#issuecomment-1022203371, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAXF2MPNPALBB5GPUDBJA3UX72EDANCNFSM5MUOYJSA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.*** com>

cburgmer commented 2 years ago

The main argument for allowing filter selectors, indeed all selectors, in the "list selector" is that it removes special cases [...]

I have so far not contributed to this discussion, and don't have a strong position myself, but I wanted to explain the quoted argument in a bit more detail.

In my (outdated) proposal for an aligned understanding, I identified two major operators: recursive decent and children selection. The latter is implemented here: https://github.com/cburgmer/json-path-comparison/blob/master/proposals/Proposal_A/operators.js#L140

If we were to exclude wildcard or filters, my code would grow. Happy to see (pseudo) code for the other side of the argument to compare.