- From: Gregg Kellogg <gregg@greggkellogg.net>
- Date: Wed, 23 Apr 2014 10:34:46 -0700
- To: Markus Lanthaler <markus.lanthaler@gmx.net>
- Cc: public-hydra@w3.org, Thomas Hoppe <thomas.hoppe@n-fuse.de>
On Apr 23, 2014, at 7:32 AM, Markus Lanthaler <markus.lanthaler@gmx.net> wrote: > Collapsing Gregg's and Thomas' threads > > On Sunday, April 20, 2014 1:56 AM, Gregg Kellogg wrote: >>> The semantics would be that a template (pseudo-code) >>> >>> hydra:filter [ >>> hydra:template "/collection?name={schema:name}" >>> ] >>> >>> that is expanded to >>> >>> /collection?name=Markus >>> >>> would return a collection in which all members correspond to the > following >>> graph pattern >>> >>> ?member schema:name "Markus" >>> >>> >>> PROPOSAL: Add a hydra:filter property with the semantics outlined above. >>> >>> Question: If we decide to support "propertyPath" in > "PropertyConstraint", >>> should we also support propert paths in IRI template mappings? This > would >>> certainly make filter much more powerful. >>> >>> https://github.com/HydraCG/Specifications/issues/45 >> >> Yes, this is something like I've been looking for; I'm not sure if > aggregations are appropriate >> here, or would be left to search (probably the later). > > What exactly do you mean by aggregations... do you mean things like > calculating sums of subsets of the members of a collection? If so, that's > not addressed at all. The only "sum" you would potentially get is the number > of members of the filtered collection. Certainly counting should come for free with a filter, which presumably returns a new Collection from which you can get totalItems. I was thinking of a hydra:search, which might return something different than a collection of resources all the same type as the class on which the search if performed (or derived from that class). I was thinking of aggregation in the form of returning simple scalar values such as MIN/MAX/SUM/COUNT, but also possibly GROUP results, in which each result might be described with a class defined in hydra:returns. This may be beyond Hydra's specific use case, but you've said that the semantics of hydra:search are intentionally vague. The problem with this, however, is that it then becomes useless for describing a contract between the client and the server, so we fall back on traditional API documentation to understand the behavior of search. A specific use case I had in mind was to be able to return information about a collection made up of heterogeneous members. You might then want to do the equivalent of a SPARQL aggregating query. I discussed this more fully at the end of my email on querying collections [1] which didn't spark any discussion. >> You'll need to explain more about URI template variable binding; It seems > that >> schema:name here is somehow used to find "Markus", perhaps in the subject > of the >> collection, and that the "name" query element is interpreted by the > service to be >> schema:name for members of the collection. It might be somewhat confusing > if it has two >> senses that aren't directly related. > > OK, I thought the pseudo code above is enough. Anyway, here is how it works: > > 1) You have a collection with several members. > 2) You define a IRI template and associate it via hydra:filter to the > collection > 3) Each variable in that IRI template is bound to a property (path) > 4) Expanding the template with concrete values results in a queries of the > form > ?member ?property "value supplied by client" > 5) Derefering the expanded IRI template returns a collection whose members > match the query criteria > > Is it clearer now? Otherwise I'll post a concrete example. So, in your example, hydra:template "/collection?name={schema:name}", the {schema:name} portion of the template is interpreted both by the service and the client? When the client makes the template concrete by replacing {schema:name} with Markus, the server knows to bind the "name" query parameter with the schema:name property path and reverse this logic. It's not explicit in this snippet, but I presume there is a mapping that binds "name" to schema:name, in which case wouldn't the template be "/collection{?name}" (per Example 15 from the spec). The server understands "name" to be bound to "schema:name", because of the mapping, and RFC6570 describes how to construct a query presuming that "name" is bound to a concrete value; if it were bound to "Markus", this would create "/collection?name=Markus". Presumably, unbound variables are just eliminated from the URI Template. >> From a client's perspective, I would think that these variables would be > used to drive HTML >> form fields, or similar. Is the purpose of specifying the predicate, then, > to get the range and >> description to build such a form entry? Explaining the motivation behind > doing this would >> be useful. > > Yes, you could use it to render a form or you could present all the members > of a collection in the form of a spreadsheet: > > <memberUrl> | property1 | property2 | ... | propertyN > > You could then filter that table by the properties that appear in the > hydra:filter IRI template. Ok. > Thomas has also a good point: > >> On Sunday, April 20, 2014 1:40 PM, Thomas Hoppe wrote: >> I would appreciate the support of filtering as I have mentioned on >> other posts but the proposed approach as far as I have understood it >> has the major disadvantage that I would need to define a filter for >> each property of collection members on which I want to offer >> filtering. This can become quite lengthy. > > Yeah, that's true. You would need to specify them explicitely. We should say something about the role of sub-classing with Hydra operations and constraints. If I define a constraint on schema:Event that defines a hydra:TemplatedLink, can we infer that this is also a constraint on something like schema:SportsEvent? Looking at it the other way, a schema:SportsEvent is also a schema:Event through RDFS inference, so operations and constraints defined on the such an instance would presumably also be appropriate for such a resource. >> I opt for a more generic approach which allows the client to pick >> arbitrary properties and filter for them -- something like this: >> >> hydra:filter: { >> @type: "IriTemplate", >> template: "?f={property}:{value}", >> mappings: [ >> { >> @type: "IriTemplateMapping", >> variable: "property", >> property: "rdf:Property", >> required: true >> }, >> { >> @type: "IriTemplateMapping", >> variable: "value", >> required: true >> } >> ] >> } > > Using rdf:Property this way is ambigous as you wouldn't know whether the > server just supports filterting for rdf:Property or all properties. > > >> This would also allow for templates like this: >> >> template: "?{property}={value}" > > The other problem with this approach ist hat {property} would have to be > expanded to a full URL as otherwise. So you would end up with very long and > ugly URLs. So? >> Which would allow to describe the diversity of current filtering >> notations found in APIs. > > I don't know of many APIs that allow completely arbitrary filtering. Most of > them are quite restricted... which makes sense because filtering might be a > quite costly operation especially if there are lots of properties. If you > really want to allow completely arbitrary filtering, it might actually make > more sense to just send a SPARQL query or something similar. I'm not sure. > Thoughts? I think basic filtering using property paths is a pretty important use case. We might constrain the length of these paths, as not every implementation will be done using a SPARQL back end. But, for my part, I'm fine with limiting filters to property paths defined as specific mappings within an TemplatedLink. Gregg [1] http://lists.w3.org/Archives/Public/public-hydra/2014Apr/0028.html > -- > Markus Lanthaler > @markuslanthaler >
Received on Wednesday, 23 April 2014 17:35:17 UTC