RE: Moving forward with hydra:filter (ISSUE-45)

On 31 Okt 2015 at 14:19, Ruben Verborgh wrote:
>>> This would be my suggested semantics for hydra:filter:
>>> it's the specific case in which we combine conditions with AND.
>>> Other predicates can be implemented differently;
>>> they all can derive from hydra:search.

I don't think having different predicates for different logical operators
scales. Especially not if you consider that the number of parameters varies.
So we should come up with something else.

>> I'd change the hydra:filter to something else. Other, more generic
implementations could
> fit better to the word "filter". Something like "matchAll" would be more
suitable.
> 
> Another name might be helpful indeed.

IMO, hydra:filter describes the purpose of the referenced IRI templated very
well. I would thus propose to stick to it for the time being and explore
design that allow to make the IriTemplate at the other end more expressive.


>>>>>>>> - if a parameter value is empty, it is ignored (i.e., an empty
value does
>>>>>>>> not mean the property needs to be empty)
>>>> 
>>>> How will we be able to express that then?
>>>
>>> This would require ExplicitRepresentation and "".

Why should an ExplicitRepresentation be interpreted differently? Or are you
saying that *no value* (instead of an empty string) of a property with
ExplicitRepresentation represents a wildcard (match-all) then? So

   ?property=&otherProperty=1  vs.  ?property=""&otherProperty=1 
   (ignoring encoding of the quotes)


Let's see how we could make the filter more expressive. The current proposal
is to implicitly combine the first and last parameters in the following
IriTemplate with AND

   </collection> :filter [
     rdf:type :IriTemplate ;
     :template "/collection{?first,last}" ;
     :mapping [ :variable "first"; :property schema:givenName ] ;
     :mapping [ :variable "last"; :property schema:familyName ] .
   ] .

An option to make this more flexible would be to explicitly describe that.
Maybe something along these lines:

   </collection> :filter [
     rdf:type :IriTemplate, :Filter ;
     :filterSpecification [
       rdf:type :AndFilter ;
       :input [ :variable "first" ] ;
       :input [ :variable "last" ] .
     ] ;
     :template "/collection{?first,last}" ;
     :mapping [ :variable "first"; :property schema:givenName ] ;
     :mapping [ :variable "last"; :property schema:familyName ] .
   ] .

This would allow to nest filters to describe more complicated expressions:

   </collection> :filter [
     rdf:type :IriTemplate, :Filter ;
     :filterSpecification [
       rdf:type :OrFilter ;
       :input [ :variable "name" ] ;
       :input [
         rdf:type :AndFilter ;
         :input [ :variable "first" ] ;
         :input [ :variable "last" ] .
       ] .
     ] ;
     :template "/collection{?name,first,last}" ;
     :mapping [ :variable "name"; :property schema:name ] ;
     :mapping [ :variable "first"; :property schema:givenName ] ;
     :mapping [ :variable "last"; :property schema:familyName ] .
   ] .

Here the filter would be "name OR (first AND last)". While this is quite
straightforward I think, it puts quite a burden on the client. Assume that
the client wants to filter a collection in a specific way. It would need to
be able to check whether his query can be accepted directly by the server or
whether it needs to rewrite the query into simpler subqueries or generalize
the query and complement it with some additional client side querying.

A simpler alternative could look somewhat like this but is not as expressive
as it doesn't allow grouping (the typical order of precedence is NOT, AND,
OR) and is less intuitive:

   </collection> :filter [
     rdf:type :IriTemplate, :Filter ;
     :variableRepresentation: FilterRepresentation ;
     :template "/collection{?name,first,last}" ;
     :mapping [
       :variable "name" ;
       :property schema:name ;
       :allowedOperators "NOT", "OR" .
     ] ;
     :mapping [
       :variable "first" ;
       :property schema:givenName ;
       :allowedOperators "NOT" .
     ] ;
     :mapping [
       :variable "last" ;
       :property schema:familyName ;
     ] .
   ] .

If no operator is given, it would default to AND. This would allow to the
following expressions (I hope I didn't forget any):

   name AND first AND last
   NOT name AND first AND last
   NOT name OR first AND last
   name OR first AND last

   name AND NOT first AND last
   NOT name AND NOT first AND last
   NOT name OR NOT first AND last
   name OR NOT first AND last

While it might be easier for a client to check if a query is supported by
the server or not, I find this a bit too hard to understand.

Any other ideas?


--
Markus Lanthaler
@markuslanthaler

Received on Sunday, 1 November 2015 17:58:10 UTC