Using the 'GRAPH' keyword in SPARQL to fetch remote graphs
I'm looking to use SPARQL for a relatively basic task: Given a FOAF graph, I'd like to parse the elements I find in there, get their tags (if they开发者_StackOverflow中文版 exist) and then, use those as new graphs from which to find information about those people.
So for instance, you could imagine a simple use case where I want to run a SPARQL query to list all of my favorite foods (as per my FOAF file), and also the favorite foods of all my friends.
Here is what this looks like at the moment. Note that for testing purposes, at the moment all I'm trying to do with the query below is fetch the name of the friend, through the ?name3 variable. Running this query doesn't return any results for ?graph and ?name3, even though I know that the rdfs:seeAlso link to some valid RDF files, of which at least two should have a name attribute. Thanks for any input you might have!
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?name1 ?name2 ?graph ?name3
FROM <my-rdf-file>
WHERE {
?person1 foaf:knows ?person2 .
?person1 foaf:name ?name1 .
?person2 foaf:name ?name2 .
OPTIONAL {
?person2 rdfs:seeAlso ?graph .
GRAPH ?graph {
?person3 foaf:name ?name3 .
}
}
}
GRAPH doesn't implicitly fetch remote data into the store, that would be too much of a security risk. There may be some systems where you can enable this, but it's non-standard.
However, in SPARQL 1.1 Update, there's a keyword LOAD, which does this though, you can write:
LOAD <uri>
Which will fetch the graph into the store, so you could write:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?graph
FROM <my-rdf-file>
WHERE {
?person1 foaf:knows ?person2 .
?person1 foaf:name ?name1 .
?person2 foaf:name ?name2 .
OPTIONAL {
?person2 rdfs:seeAlso ?graph .
}
}
Feed the bindings for ?graph into a set of LOAD statements, and then run your original query.
N.B. in some systems, e.g. 4store you need to enable LOAD, it's not allowed by default, so check the documentation of the store you're using.
Instead of using LOAD, once you have discovered the graphs that you need to include, as per Steve's example above, wouldn't it be reasonable to alternatively use FROM NAMED , stating all the relevant graphs in the resulting query i.e
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?name1 ?name2 ?name3
FROM <my-rdf-file>
FROM NAMED <discovered-graph-URI-1>
FROM NAMED <discovered-graph-URI-n>
WHERE {
GRAPH <my-rdf-file> {
?person1 foaf:knows ?person2 .
?person1 foaf:name ?name1 .
?person2 foaf:name ?name2 .
}
OPTIONAL {
?person2 rdfs:seeAlso <discovered-graph-URI-1> .
GRAPH <discovered-graph-URI-1> {
?person3 foaf:name ?name3 .
}
?person2 rdfs:seeAlso <discovered-graph-URI-n> .
GRAPH <discovered-graph-URI-n> {
?person3 foaf:name ?name3 .
}
}
}
That way you get round the security issues and you don't have to maintain the data in your own triplestore.
精彩评论