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:
1)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)
2)FILTER
e.g:
SELECT * WHERE
{
?s ?p ?o.
FILTER (?p = :propA || ?p = :propB )
}
Any other ideas?
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 .
}
}
}