简体   繁体   中英

Sparql, how to merge different results

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM