I don't quite understand why in SPARQL they haven't implemented the basic logic operators. However in most of the cases is possible to obtain the same result in a number of way.
The purpose of this question is to have a quick reference for the possible way troughs that can substitute an "or" statement.
Here's what I can think of:
UNION
e.g:
SELECT * WHERE { { ?s :propA ?o } UNION { ?s :propB ?o } }
-not often suitable because it can became very verbose because
SELECT * WHERE { { GRAPH ?g {?s ?p ?o. ?o ?pp ?data1}} UNION { GRAPH ?g {?s ?p ?o. ?o ?pp ?data2}} }
doesn't work as
SELECT * WHERE { GRAPH ?g { ?s ?p ?o. {?o ?pp ?data1} UNION {?o ?pp ?data2} } }
(at least not with Stardog)
FILTER
e.g:
SELECT * WHERE { ?s ?p ?o. FILTER (?p = :propA || ?p = :propB ) }
Any other ideas?
"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.
SPARQL allows for a query to consist of triple patterns, conjunctions, disjunctions, and optional patterns. Implementations for multiple programming languages exist. There exist tools that allow one to connect and semi-automatically construct a SPARQL query for a SPARQL endpoint, for example ViziQuer.
SPARQL sees your data as a directed, labeled graph, that is internally expressed as triples consisting of subject, predicate and object. Correspondingly, a SPARQL query consists of a set of triple patterns in which each element (the subject, predicate and object) can be a variable (wildcard).
I'm not entirely sure why you say SPARQL doesn't supply 'the basic logic operators', because your own examples clearly show that it does: it provides logical-OR (||
) and logical-AND (&&
) as part of FILTER
conditions, and disjunctive graph patterns using UNION
(of course, conjunctive graph patterns need no special syntax).
Other variations of OR
-like constructs are also possible. For queries of the form "this particular value must be one of these possibilities" you can use the set membership operator, IN
:
SELECT * WHERE { ?s ?p ?o. FILTER (?p IN (:propA, :propB, :propC ) ) }
You can also use the VALUES
clause for this kind of pattern:
SELECT * WHERE { VALUES ?p { :propA :propB :propC } ?s ?p ?o. }
Update I forgot one, perhaps the simplest. For queries such as yours, where you are looking for a few alternatives for a property name, you can actually use a property path expression as well, like so:
SELECT * WHERE { ?s :propA|:propB|:propC ?o. }
If you want to trace which predicate lead to which object then this is universal solution for "OR" :
SELECT DISTINCT ?s ?o1 ?o2 WHERE { { ?s p1 ?o1 . OPTIONAL { ?s p2 ?o2 . } } UNION { ?s p2 ?o2 . OPTIONAL { ?s p1 ?o1 . } } }
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