Search code examples
sparqltriplestoretriples

SPARQL query for some kind of START WITH and CONNECT BY (Oracle)


I'm busy with a proof of concept working with a triple store. I have the following structure:

enter image description here

There are 2 relation types defined (triples). Top-down relation where the child is part of ("isPartOf" its parent and left-right where there are childs that CAN (optional) be replaced ("replaces") by another version of the child.

Also every child have a "isValidStart" triple with a date as object. This means that this child is valid since that date. The last child in a horizontal childgroup can have a relation "isInvalidEnd" that means that after this date this group is invalid.

What I want to do is to build a SPARQL query where I can get the childs of a parent on a specific date. Is that possible with SPARQL and how can I do that?

I know that there is in Oracle any kind of START WITH / CONNECT BY function that do some kind of this stuff...but how do I this in SPARQL world.

Thanks

</metadata/puid/test2> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test1" .
</metadata/puid/test2> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test3> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test2" .
</metadata/puid/test3> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test4> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test3" .
</metadata/puid/test4> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test5> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test4" .
</metadata/puid/test5> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test6> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test4" .
</metadata/puid/test6> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test7> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test4" .
</metadata/puid/test7> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test8> <http://purl.org/dc/terms/replaces> "/metadata/puid/test7" .
</metadata/puid/test8> <http://purl.org/dc/terms/isValidStart> "2015-07-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test9> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test5" .
</metadata/puid/test9> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test10> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test5" .
</metadata/puid/test10> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test11> <http://purl.org/dc/terms/isPartOf> "/metadata/puid/test5" .
</metadata/puid/test11> <http://purl.org/dc/terms/isValidStart> "2015-04-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test12> <http://purl.org/dc/terms/replaces> "/metadata/puid/test9" .
</metadata/puid/test12> <http://purl.org/dc/terms/isValidStart> "2015-07-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test13> <http://purl.org/dc/terms/replaces> "/metadata/puid/test10" .
</metadata/puid/test13> <http://purl.org/dc/terms/isValidStart> "2015-05-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test14> <http://purl.org/dc/terms/replaces> "/metadata/puid/test13" .
</metadata/puid/test14> <http://purl.org/dc/terms/isValidStart> "2015-08-01"^^<http://www.w3.org/2001/XMLSchema#date> .
</metadata/puid/test14> <http://purl.org/dc/terms/isValidEnd> "2015-12-01"^^<http://www.w3.org/2001/XMLSchema#date> .

// disclaimer: I'm new in SPARQL world


Solution

  • I worked on a solution and I found a working solution. I put this method in a function that I can use to find the valid childs below that item (parent). I get a complete tree, with only valid items, when calling this function recursively.

    PREFIX : <http://purl.org/dc/terms/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    
    SELECT  ?child ?startDate ?endDate
    WHERE
    { 
        # get the valid start values 
        ?child  :isValidStart  ?startDate
    
    
        BIND(iri("'||$parent||'") as ?parent) 
        FILTER EXISTS{ {?child :isPartOf ?parent }
                      UNION { 
                        ?child (:replaces)+ ?prevVersion .
                        ?prevVersion :isPartOf ?parent
                       } 
                     }
        # and there was no other valid replacing child
        FILTER NOT EXISTS { ?replacer  :replaces  ?child ;
                                       :isValidStart ?startDateReplacer
                            FILTER (?startDateReplacer <= "'||$selectionDate||'"^^xsd:date)
                          } 
    
        # where the start was before/at the given date
        FILTER(?startDate <= "'||$selectionDate||'"^^xsd:date)
    
        OPTIONAL { ?child :isValidEnd ?endDate }
    
        # and not end date is before/at selection date        
        FILTER NOT EXISTS { FILTER (?endDate <= "'||$selectionDate||'"^^xsd:date) }        
     }