21

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?

| improve this question | |
  • I'm sorry, but what do you mean when you say the first query "don't work as" the second query? Are you expecting those two queries to do the exact same thing? – Jeen Broekstra May 28 '15 at 10:50
  • if UNION would work exactly like a logical-OR the 2 queries would have produced the same result, but of course they don't. I'm sorry that I can't explain myself properly, I'm a sparql newbie and also English is not my mother tongue, thank you for your comprehension and your time. – ffa May 28 '15 at 12:11
  • @ffa We're getting off on a tangent here I guess, but you are under a misconception that UNION is somehow different from a logical-OR. They are semantically the exact same thing, however. The reason the two queries are different is simply one of scoping. The first query is ((?s ?p ?o ?g) AND (?o ?pp ?data1 ?g)) OR ((?s ?p ?o ?g) AND (?o ?pp ?data2 ?g)), the second query is (?s ?p ?o ?g) AND ((?o ?pp ?data1 ?g) OR (?o ?pp ?data2 ?g)). – Jeen Broekstra May 28 '15 at 18:20
  • ...and no worries about your English, it's fine, and if I don't understand something you say I just ask you to explain (and I hope you do the same to me) :) – Jeen Broekstra May 28 '15 at 18:27
34

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.
}
| improve this answer | |
  • I mean that you can use the basic logic operators only inside a FILTER condition. In my (limited) experience a more comprehensive implementation would have been handy in a lot of situations. The UNION statement often is not an option because you can't nest it. Anyway thank you for your precious contribution. – ffa May 28 '15 at 9:56
  • Actually, you can nest UNIONs just fine. I'd be interested to see a disjunctive graph pattern that you think cannot be expressed using UNION - if you have an example can you edit your question to that effect? – Jeen Broekstra May 28 '15 at 9:58
  • yeha, but for example SELECT * WHERE{ { GRAPH ?g {?s ?p ?o. ?o ?pp ?data1} UNION { GRAPH ?g {?s ?p ?o. ?o ?pp ?data2} } don't work as SELECT * WHERE{ { GRAPH ?g {?s ?p ?o. {?o ?pp ?data1} UNION { ?o ?pp ?data2} } (at least with Stardog) – ffa May 28 '15 at 10:05
  • 1
    @JeenBroekstra: does | work for the object as well? e.g. ?a a :object1|:object2. I have actually tried and it didnt work. But I might have been doing something wrong!!! – msc87 Aug 3 '17 at 13:28
  • 2
    @msc87, no, property path expressions only work for properties. For objects, you will have to use one of the other constructs. – Jeen Broekstra Aug 3 '17 at 22:48
3

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 .
     }
  }
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.