3
votes

Hi all I'd like to discover if there is a relation between two nodes and if any the predicates connecting them. Let's say my graph is like following

                    [Uri1]
                 /          \
          (pred:a)          (pred:b)    
         /      \           /       \
    [Uri2]      [Uri3]  [Uri4]      [Uri5]
    /     \ 
(pred:c) (pred:d)  
  /             \
[Uri6]         [Uri7]
                  \
                  (pred:a)
                     \
                     [Uri8]

If the query is looking for the relations between Uri8 and Uri1, the expected result should be

[Uri7] = pred:a

[Uri2] = pred:d

[Uri1] = pred:a

Consider that predicates (relations) between nodes may vary and also lengths.

the two following: SPARQL: is there any path between two nodes? and Is it possible to return relationships between two objects in SPARQL? do not work

1
I don't think this is possible with SPARQL. It's not designed for such kind of graph traversal things. You could get the intermediate nodes by using property paths, but in that case you'll loose the predicates. The only way I think would work is to incrementally send queries with more hops between both resources. Otherwise you need to load the data into some graph database and use it's query language. - UninformedUser
@AKSW This is definitely possible with SPARQL, and I've added an answer. The trick is to use two wildcard paths: one for the first portion of the path, and one for the last portion of the path, and then to get the values from the triple that joins them. - Joshua Taylor
@RobMor The first question that you linked to has, in the comments, a link to Finding all steps in property path, which is very similar to this. The accepted answer says it's not possible, but my answer actually shows that you can do it. - Joshua Taylor
@Joshua Taylor Thanks, nice solution.See some comments below your answer. - UninformedUser

1 Answers

2
votes

The approaches in those questions do work, although the explanations in Is it possible to get the position of an element in an RDF Collection in SPARQL? and Finding all steps in property path might help even more in understanding the solution. Here's some data to test with, if I've understood your example correctly:

@prefix : <urn:ex:>

:uri1 :a :uri2, :uri3 ;
      :b :uri4, :uri5 .

:uri2 :c :uri6 ;
      :d :uri7 .

:uri7 :a :uri8 .

Here's the query. The idea is to follow a wildcard path from the beginning (:uri1) to some point ?x. Then we take a link from ?x to its object ?o, and then find a wildcard path from ?o to the ?end (:uri8). (Note that I'm using (:|!:) as a property wildcard; it matches everything since every IRI is either : or not :.)

prefix : <urn:ex:>

select ?x ?p where {
  :uri1 (:|!:)* ?x .
  ?x ?p ?o .
  ?o (:|!:)* :uri8 .
}

The results are just like what you asked for:

--------------
| x     | p  |
==============
| :uri1 | :a |
| :uri2 | :d |
| :uri7 | :a |
--------------