I am trying to create a SPARQL query to find all the people that Jim knows, then to find which people the knowers of Jim know and then the same thing like a chain.
For example I have that:
Jim knows Clare and Antoine
Clare knows Jim and David
Antoine knows David and Clare
David knows Clare
So the results are then:
result1: Clare, Antoine
result2: Jim, David, David, Clare
result3: Clare, David, Clare, Clare, Jim, David
More or less I have made something like a tree.
What I want is to merge result1
, result2
and result3
into result4
. So the result4
will be:
result4: clare, antoine, jim, david, david, clare, clare, david, clare, clare, jim, david.
and then to use DISTINCT
to remove the duplicates. How can I achieve this please?
SELECT ?Result1 ?Result2 ?Result3
WHERE{
{
base:Knows dc:Names _:BN1 .
_:BN1 dc:FName "Jim";
dc:KnownFName ?Result1 .
}
.
{
base:Knows dc:Names _:BN2 .
_:BN2 dc:FName ?Result1;
dc:KnownFName ?Result2 .
}
.
{
base:Knows dc:Names _:BN3 .
_:BN3 dc:FName ?Result2;
dc:KnownFName ?Result3 .
}
}
Let's say your example is represented as follows:
<http://example.com/person/1> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/2> .
<http://example.com/person/1> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/3> .
<http://example.com/person/2> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/1> .
<http://example.com/person/2> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/4> .
<http://example.com/person/3> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/4> .
<http://example.com/person/3> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/2> .
<http://example.com/person/4> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/2> .
<http://example.com/person/1> <http://www.w3.org/2000/01/rdf-schema#label> "Jim" .
<http://example.com/person/2> <http://www.w3.org/2000/01/rdf-schema#label> "Clare" .
<http://example.com/person/3> <http://www.w3.org/2000/01/rdf-schema#label> "Antoine" .
<http://example.com/person/4> <http://www.w3.org/2000/01/rdf-schema#label> "David" .
Then you can use SPARQL's UNION feature to achieve what you want by merging the result of three separate queries. It can be expressed more succinctly using SPARQL property paths:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT * WHERE {
{ SELECT * WHERE {
<http://example.com/person/1> foaf:knows/rdfs:label ?knowsName .
} }
UNION
{ SELECT * WHERE {
<http://example.com/person/1> foaf:knows/foaf:knows/rdfs:label ?knowsName .
} }
UNION
{ SELECT * WHERE {
<http://example.com/person/1> foaf:knows/foaf:knows/foaf:knows/rdfs:label ?knowsName .
} }
}
You can also get the full transitive closure of the knows
predicate via a single property path expression:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT * WHERE {
<http://example.com/person/1> foaf:knows+/rdfs:label ?knowsName .
}
...if your triplestore supports SPARQL 1.1. Otherwise you would have to use reasoning or repeated queries to get the full closure.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.