sparql.anything icon indicating copy to clipboard operation
sparql.anything copied to clipboard

Reusing queries

Open enridaga opened this issue 3 years ago • 8 comments

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

enridaga avatar Dec 09 '21 13:12 enridaga

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.

enridaga avatar Dec 09 '21 13:12 enridaga

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

luigi-asprino avatar Dec 10 '21 11:12 luigi-asprino

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)

enridaga avatar Dec 10 '21 11:12 enridaga

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?

enridaga avatar Dec 10 '21 11:12 enridaga

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 ] 
     .
}

enridaga avatar Dec 10 '21 12:12 enridaga

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

justin2004 avatar Dec 10 '21 13:12 justin2004

Additionally, queries can be parametrised and parameters passed via options:

:+1:

justin2004 avatar Dec 10 '21 13:12 justin2004

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
}

enridaga avatar May 02 '22 16:05 enridaga