0

Lets's say I have the following RDF graph:

@prefix :  <http://example/> .

:order1  :item :z1 .
:order2  :item :z2 .

:z1 :name "Small" .
:z1 :price 5 .

:z2 :name "Large" .
:z2 :price 5 .

I want a SPARQL query to select all triples that describe :z1. i.e. all triples that are children or children of children (etc.) of :z1. So far from what I found this is called an arbitrary-length property path with arbitrary properties. I have used solutions from SPARQL property path queries with arbitrary properties and Sparql - query to get all triples related to a specific subject to come up with this query:

PREFIX : <http://example/>
SELECT ?s ?p ?o
WHERE {
    ?s ?p ?o .
    :order1 (<>|!<>)+ ?o .  # Match arbitrary-length property path with arbitrary properties 
}

Which results in (in ttl format):

@prefix : <http://example/> .

:order1 :item :z1 .

:z2 :price 5 .

:z1 :name "Small" ;
    :price 5 .

As you can see this also selects the :z2 :price 5 . triple, which I did not expect and is also not what I want. For some reason, it seems like the inverse :price path inference from object 5 to subject :z2 is also included.

How do I achieve selecting all triples included in the arbitrary-length property path of :z1 with arbitrary but directed properties?

NB: This is a simplified version of the real problem I try to solve where the predicates in the path and the length of the path can indeed be arbitrary.

Perhaps this drawing helps: Visualisation of the problem

  • 1
    why not expect `:z2 :price 5 .` ? You're basically getting all objects `?o` on a path starting from `:order1`, right? But then you get all incoming edges, i.e. triples where each `?o` on the path is the object of the triple resp. the target node of the edge. I do not understand why you do this but it's not what you want. From my understanding you want to get all outgoing edges, or not? So you should handle all objects on the path as the subject: `?s ?p ?o . :order11 (<>|!<>)+ ?s .` – UninformedUser Dec 29 '20 at 18:42
  • 1
    @UninformedUser you are completely right! I hope the answer I proposed is a good translation of your comment. – Sven van der Burg Dec 31 '20 at 14:33

1 Answers1

1

As mentioned by @UninformedUser I was getting all incoming edges starting from :order1, whereas I want all outcoming edges.

The correct query would be:

PREFIX : <http://example/>
SELECT ?s ?p ?o
WHERE {
    ?s ?p ?o .
    :order1 (<>|!<>)* ?s .  # Match arbitrary-length property path with arbitrary properties 
}

Where I changed ?o to ?s in :order1 (<>|!<>)+ ?o . so I only match outgoing edges, i.e. triples on the path where the subject (?s) is the target of a 'mother' triple.

I also changed + to * in :order1 (<>|!<>)+ ?o . so I match paths of length 0 or more instead of 1 or more so I also get the triples where :order1 is the subject.