"or" in a SPARQL query
Asked Answered
S

2

48

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?

Solubilize answered 28/5, 2015 at 8:28 Comment(4)
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?Wagtail
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.Solubilize
@Solubilize 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)).Wagtail
...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) :)Wagtail
W
63

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.
}
Wagtail answered 28/5, 2015 at 9:37 Comment(8)
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.Solubilize
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?Wagtail
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)Solubilize
Also not entirely sure what you imagine this "more comprehensive implementation" should look like. Can you give some example of the kind of thing that you'd like to be able to write in SPARQL?Wagtail
@Solubilize adding SPARQL queries in comments makes them almost impossible to read - can you instead add these examples to your question so they can be properly formatted?Wagtail
@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!!!Rehm
@msc87, no, property path expressions only work for properties. For objects, you will have to use one of the other constructs.Wagtail
Thanks for this explanation - I have tried all three and have discovered some interesting performance implications. With Apache Jena, for example, the property path variant is by far the slowest. Do you have any hint as to why that might be?Kolinsky
C
6

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 .
     }
  }
}
Cineaste answered 23/2, 2017 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.