Search code examples
sparqlrdfsubgraph

How to execute SPARQL Query (Call a service) Over extracted subgraph?


I have a RDF graph with several types of relations (relations with the same prefix and with different prefixes also). I need to call a service over the graph but filtering out some relations.

Example: enter image description here

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix myPref: <http://www.myPref.com/>.
@prefix otherPref: <http://www.otherPref.com/>.

myPref:1
    myPref:label "1" ;
    myPref:solid myPref:2 ;
    myPref:dotted myPref:4 ;
    otherPref:dashed myPref:3 ;
    otherPref:dashed2 myPref:3 .

myPref:2
    myPref:label "2" ;
    myPref:solid myPref:3 .

myPref:3
    myPref:label "3" .

myPref:4
    myPref:label "4" ;
    myPref:dotted myPref:3 .

I would like to run the service call over an extracted sub-graph containing only the solid and dotted relations (In this particular case, running a service calculating the shortest path between 1 to 3, I want to exclude those direct links).

I run the service (Over the entire graph) like this:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
PREFIX myPref: <http://www.myPref.com/>.
PREFIX otherPref: <http://www.otherPref.com/>.
PREFIX gas: <http://www.bigdata.com/rdf/gas#>

SELECT ?sp ?out {
  SERVICE gas:service {
     gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" .
     gas:program gas:in myPref:1 .
     gas:program gas:target myPref:3 . 
     gas:program gas:out ?out . 
     gas:program gas:out1 ?sp . 
  }
}

How can I extract a subgraph containing only the links I want (Dotted and solid) and the run the service call over the extracted sub-graph?


Solution

  • SPARQL doesn't provide any functionality for querying a constructed graph, unfortunately. I've come across places where it would make some queries very easy. Some endpoints do have extensions to support it, though. I think that dotNetRDF might support it. There are probably a few aspects: in many cases, it's not actually necessary; if the endpoint supports updates, you can create a new named graph and construct into it, and then launch a second query against it (which is pretty much what you're asking for, but in two steps); this could be a very expensive operation, so endpoints might disable it anyway, even if it was directly supported.

    The first note, though, that it's often times not necessary, appears that it might be the case here.

    I need to call a service over the graph but filtering out some relations.

    In this case, you can query over the subgraph that you want, I think, by using property paths. You can ask for paths built from just solid and dashed edges like:

    ?s  myPref:solid|myPref:dotted ?t
    

    If you want an arbitrary path of them, you can repeat it:

    ?s  (myPref:solid|myPref:dotted)+ ?t
    

    If you have unique paths between sources and destinations, then you can figure out the lengths of paths using the standard "count the ways of splitting the path" technique:

    select (count(?t) as ?length) {
      ?s  (myPref:solid|myPref:dotted)* ?t
      ?t  (myPref:solid|myPref:dotted)* ?u
    }
    group by ?s ?t