sparql.anything
sparql.anything copied to clipboard
Reusing queries
I think this functionality merits its own issue.
This may not be what you are talking about here but I am still interested specifying multiple queries. I talked about this here. e.g.
service <x-sparql-anything:query.location=/mnt/first.rq>
service <x-sparql-anything:query.location=/mnt/second.rq>
Where first.rq might be defined by an ontology team and second.rq is your application's query and it operates on the triples constructed by first.rq.
Originally posted by @justin2004 in https://github.com/SPARQL-Anything/sparql.anything/issues/150#issuecomment-975512207
I like the idea of using SERVICE clauses to glue existing queries altogether. In the case of SELECT queries this is trivial, I am unsure about how to handle CONSTRUCT queries -- I guess we need an additional BGP to be in the enclosing SERVICE clause, otherwise we throw an error. Probably ASK and other type of queries should not be allowed.
I see more criticisms with SELECT queries rather than CONSTRUCT queries. As for the CONSTRUCT queries, the expected behaviour should be (as you suggest): 1) executing the CONSTRUCT query provided and 2) evaluating the BGP inside the SERVICE clause against the result of the construct query. But I cannot see how to integrate SELECT clause. We probably need a sort of iterator. Maybe we can design a BGP to iterate over the result of a select query. For example
SERVICE<selectquery.sparql> {
[] rdf:_1 ?variable_1 ;
rdf:_2 ?variable_2 .
}
or
SERVICE<selectquery.sparql> {
[] rdf:variableName ?variable_1 ;
rdf:variableName2 ?variable_2 .
}
If it is a SELECT query, then no pattern is allowed inside (I thought this was the intended use of the service clause with provided external query)
Ah! What @luigi-asprino is suggesting is to interpret the SELECT query as tabular data! This is also possible, applying the same FX-based transformation -- but I would leave it as an optional feature. The basic behaviour could be that, if the imported SELECT projects var ?x
then that will be the var projected by the SERVICE clause to the query executor. Makes sense?
Additionally, queries can be parametrised and parameters passed via options:
SERVICE<x-sparql-anything:> {
fx:properties fx:query "select-query.sparql" ;
fx:param [ fx:var "x" ; fx:value "10"^xsd:int ] ;
fx:param [ fx:var "y" ; fx:value "Bob"^xsd:string ]
.
}
If it is a SELECT query, then no pattern is allowed inside (I thought this was the intended use of the service clause with provided external query)
I was thinking that the referenced query should be a construct query but that the "outer query" could be a select or a construct.
e.g. I save this as /app/a.rq
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
prefix schema: <http://schema.org/>
construct {
?s ?p ?o .
# pretend I produced interesting triples using schema.org
}
WHERE {
service <x-sparql-anything:>{
fx:properties fx:location "https://some.internal/api/v1/systemQ/list-radio" .
fx:properties fx:media-type "application/json" .
graph ?g {?s ?p ?o }.
}
}
Then I want to be able to tell people that they can run queries like this:
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
prefix schema: <http://schema.org/>
select distinct ?radioChannelName
WHERE {
?s a schema:AMRadioChannel .
?s schema:name ?radioChannelName .
service <x-sparql-anything:>{
fx:properties fx:query.location "/app/a.rq" .
}
Notice how the people that run that query don't even have to know about "https://some.internal/api/v1/systemQ/list-radio".
Additionally, queries can be parametrised and parameters passed via options:
:+1:
I see three scenarios:
1 - execute SELECT query and use output
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
prefix schema: <http://schema.org/>
select distinct ?radioChannelName
WHERE {
service <x-sparql-anything:> {
fx:properties fx:query.location "/app/aSelect.rq" .
# inner select return query solution of tuples / variables (e.g. ?radioChannelName)
# BGP forbidden OR we can interpret the output of the Select via FX:
fx:properties fx:query.asfx "true" . # interpret query output via FX
filter ( ... )
BIND ( ... )
}
2 - execute CONSTRUCT query and use output
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
prefix schema: <http://schema.org/>
select distinct ?radioChannelName
WHERE {
service <x-sparql-anything:> {
fx:properties fx:query.location "/app/a.rq" .
?s a schema:AMRadioChannel .
?s schema:name ?radioChannelName .
}
3 - chain two queries:
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
prefix schema: <http://schema.org/>
select distinct ?radioChannelName
WHERE {
service <x-sparql-anything:> {
fx:properties fx:query.location "/app/a.rq" . # if select, no need for BGP (actually BGP forbidden)
fx:properties fx:query.input "/app/b.rq" . # a construct query to use as input for the other
}