I have a SPARQL query like this
PREFIX prefix: <http://example.org/ns#>
SELECT *
WHERE
{
?x rdf:type ?type .
}
Suppose now I want to specify the type of ?type
as being either prefix:type1
or prefix:type2
; how should this be done?
SPARQL contains capabilities for querying required and optional graph patterns along with their conjunctions and disjunctions. SPARQL also supports aggregation, subqueries, negation, creating values by expressions, extensible value testing, and constraining queries by source RDF graph.
SPARQL also supports extensible value testing and constraining queries by source RDF graph. The results of SPARQL queries can be results sets or RDF graphs.
Structure of a SPARQL Query A SPARQL query comprises, in order: Prefix declarations, for abbreviating URIs. Dataset definition, stating what RDF graph(s) are being queried. A result clause, identifying what information to return from the query.
"PREFIX", however (without the "@"), is the SPARQL instruction for a declaration of a namespace prefix. It allows you to write prefixed names in queries instead of having to use full URIs everywhere. So it's a syntax convenience mechanism for shorter, easier to read (and write) queries.
Much faster than the FILTER IN
function is the use of BINDINGS
. I would highly recommend using something along the lines of the following query rather than the FILTER(?type IN (wo:Kingdon, wo:Phylum)
.
SELECT * WHERE { ?x rdf:type ?type } BINDINGS ?type {(prefix:type1) (prefix:type2)}
Using BINDINGS
allows the SPARQL engine to limit results as it is being processed rather than returning all results before filtering them. This makes returning the results much faster.
You could use UNION
e.g.
PREFIX prefix: <http://example.org/ns#>
SELECT *
WHERE {
{ ?x a prefix:type1 } UNION { ?x a prefix:type2 }
}
Note the use of a
which is a SPARQL keyword that may be used in the predicate position and corresponds to the RDF type URI http://www.w3.org/1999/02/22-rdf-syntax-ns#type
There are other ways to do this such as using FILTER
clauses with various expressions:
?type = prefix:type1
combined with the conditional or operator ||
?type IN (prefix:type1, prefix:type2)
Or you could use a VALUES
clause to specify the options for ?type
These may be better if your query is more complex and you don't want to duplicate much of the query onto both sides of the UNION
or have more that two possibilites to consider.
As Joshua mentioned, the accepted answer is no longer accurate in SPARQL 1.1.
In SPARQL 1.1, the VALUES keyword can be used but the syntax looks more complicated for use-cases like this one. However, you can write that in compact form as well:
SELECT * WHERE {
VALUES ?type { prefix:Type1 prefix:Type2 }
?x rdf:type ?type
}
You could do it using the FILTER syntax, like this:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX prefix: <http://example.org/ns#>
SELECT ?s ?p ?o ?type
WHERE {
?s a ?type .
?s ?p ?o .
FILTER(?type IN (prefix:Type1, prefix:Type2))
}
Please note that I cannot guarantee efficiency, as I do not know if the the filtering will apply after all the results will be returned or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With