2

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

Jasper Huzen
  • 1,513
  • 12
  • 26
  • 2
    Can you show the RDF data, please? And yes, this is pretty easily doable with SPARQL – UninformedUser Jul 06 '17 at 17:54
  • I add the triple's. There are some "replaces' with updated "documents" that should pick the correct one based on selection date – Jasper Huzen Jul 06 '17 at 22:45
  • Ok, thank's. Does this mean that a) given a date of a parent (group) you want to have all its children or b) do you want to have just the children that are valid for the given date? – UninformedUser Jul 07 '17 at 00:29
  • I only want 1, the most recent version of a child. Could also be none if the isValidEnd is before the selected date – Jasper Huzen Jul 07 '17 at 07:29

2 Answers2

2

Not totally sure if this is what you're asking for but comments inline:

Given date: "2015-04-01"^^xsd:date

PREFIX : <http://purl.org/dc/terms/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT  ?child
WHERE
  {
   # we have two options to check
   # 1. all children that have not been replaced 
      { 
        # get the valid start values 
        ?child  :isValidStart  ?start 
        # where the start was before the given date
        FILTER ( ?start < "2015-04-01"^^xsd:date )
        # and there was no other replacing child
        FILTER NOT EXISTS { ?otherChild  :replaces  ?child }
      }
    UNION 
   # 2. children that haven been replaced
      { 
        # start date of children that replace others
        ?child  :isValidStart  ?start ;
                :replaces      ?someChild
        # but haven not been replaced themselves
        FILTER NOT EXISTS { ?otherChild  :replaces  ?child }
        # where the start was before the given date
        FILTER(?start < "2015-04-01"^^xsd:date) 
        # and there isn't an end date before the given date
        FILTER NOT EXISTS { ?child  :isValidEnd  ?end
                            FILTER ( ?end < "2015-04-01"^^xsd:date )
                          }
      }
  }
UninformedUser
  • 8,397
  • 1
  • 14
  • 23
  • Thanks for this solution. I will test the results later today and confirm if it's working. I think that is is correct or close to – Jasper Huzen Jul 07 '17 at 07:49
  • 1
    I guess it's not what you want, but then I'll adapt the query. What might help me is to provide also a sample date and the expected result based on your already given sample data. – UninformedUser Jul 07 '17 at 07:51
  • It now returns all valid children and not only the last valid versions of the children? How do you want to have the sample data? It are only simple "emtpy" xml document for now like: https://pastebin.com/TZVLgJn7 I can deliver you a MarkLogic XQuery script to insert all the data into MarkLogic but I'm don't know what format you do require. – Jasper Huzen Jul 07 '17 at 09:26
1

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) }        
 }
Jasper Huzen
  • 1,513
  • 12
  • 26
  • I'm not sure if this is the most simple solution but it gives the expected result. I'm still learning SPARQL (new into this tech) – Jasper Huzen Jul 12 '17 at 19:51