Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive queries in SPARQL to browse collections of collections

I am trying to create an RDF graph from a Mulgara RDF store, using a Sparql query to return results. I'm just beginning to get comfortable with simple queries, effectively asking, "which objects are Members of a particular collection?"

My question is, and I would greatly appreciate any advice, whether I can take the results from this simple query and reroute them back through as the object of the query?

For example, I have this sparql query:

SELECT ?x WHERE {?x  <fedora-rels-ext:isMemberOfCollection> <info:fedora/collection:ramsey>}

With these results:

"x"
info:fedora/ramsey:ThelifeandadventuresofRobinsonCrusoe 
info:fedora/ramsey:Jackanapes 
info:fedora/ramsey:SundayJournalvol01no0219951126 
info:fedora/ramsey:Ideologyandchange 
info:fedora/ramsey:theshepherdofthepyrenees 
info:fedora/ramsey:ScenesinAmerica
...

My goal, is to then take these unique identifiers and replace the object, <info:fedora/collection:ramsey>, from the original query and run the query again.

I'm imagining a scenario where I would identify a root element in the initial query, have the results return all member objects, then return all those objects' member objects, ad infinitum...

Is this possible with Sparql queries? Specifically, I believe I'm querying a Mulgara RDF database. Any thoughts, even if its' not doable, greatly appreciated.

like image 478
ghukill Avatar asked Feb 26 '13 01:02

ghukill


1 Answers

Lets assume you have to stick to SPARQL 1.0. I believe that mulgara has limited support for SPARQL 1.1 if any.

With SPARQL 1.0 if you probably know how many levels you want to query you can do things like:

SELECT ?y WHERE {
        ?x  <fedora-rels-ext:isMemberOfCollection> <info:fedora/collection:ramsey>
        ?y  <fedora-rels-ext:isMemberOfCollection> ?x
}

Here ?y will be bound with 2nd level elements from your root. With UNIONS you can query multiple levels with one query. An example for one and two levels from root in one query:

SELECT ?x WHERE {
     {
        ?x  <fedora-rels-ext:isMemberOfCollection> <info:fedora/collection:ramsey> .
     } UNION {
        ?zz  <fedora-rels-ext:isMemberOfCollection> <info:fedora/collection:ramsey>
        ?x  <fedora-rels-ext:isMemberOfCollection> ?zz .
     }
}

The problem with this is that you do not really know at what level ?x is bound. Therefore you cannot paint a tree with this type of query. In SPARQL 1.1 this gets solved with BIND AS

SELECT ?x ?level WHERE {
     {
        ?x  <fedora-rels-ext:isMemberOfCollection> <info:fedora/collection:ramsey> .
        BIND (1 AS ?level)
     } UNION {
        ?zz  <fedora-rels-ext:isMemberOfCollection> <info:fedora/collection:ramsey>
        ?x  <fedora-rels-ext:isMemberOfCollection> ?zz .
        BIND (2 AS ?level)
     }
}

This second query will return at what level ?x is bound. You can imagine some programatically generated query with lots of unions trying to reach the max depth of the tree. If you want full support for SPARQL 1.1 if you can try to use Jena/ARQ. In Jena you can also use Property paths and with something like the following:

SELECT ?x WHERE {
    ?x  <fedora-rels-ext:isMemberOfCollection>+ <info:fedora/collection:ramsey> .
}

You would bind in ?x all the nodes reachable from <info:fedora/collection:ramsey> via the predicate <fedora-rels-ext:isMemberOfCollection>.

like image 141
Manuel Salvadores Avatar answered Nov 18 '22 08:11

Manuel Salvadores