SPARQL is weird…
It really is. The following query is the only way I found to exclude folders when looking for files:
select ?r where {
?r a nfo:FileDataObject .
OPTIONAL { ?r2 a nfo:Folder . FILTER(?r = ?r2) . } .
FILTER( !BOUND(?r2) ) .
}
Now to me this looks really weird. And maybe I am simply not seeing the wood for all the trees…




Yes, this syntax is very inconvenient but the SPARQL WG is working on a simpler one, see http://www.w3.org/TR/2009/WD-sparql-features-20090702/#Negation and http://www.w3.org/TR/2009/WD-sparql11-query-20091022/#negation
No, you are seeing it right. The lack of any convenient way to do negation is one of the most commonly asked for features in SPARQL. To that end, the 2nd SPARQL Working Group is currently working on standardizing a more straightforward way of asking queries like this. The exact syntax is still very much up in the air, but your query above will probably look something like:
select ?r where {
?r a nfo:FileDataObject .
NOT { ?r a nfo:Folder }
}
Lee
yeah, that would be nice. Sadly it seems that Virtuoso does not implement negation yet. Well, I suppose it will soon…
Yup. That’s look like what I ended up with for some media-related queries I’m doing for Bangarang. I don’t feel like a complete idiot now. :-)
Shouldn’t it be FILTER(?r == ?r2) ??
Yes, of course. thanks. For some reason copy and paste does not work in firefox anymore here.
Re negation using Virtuoso SPARQL extensions see: http://stackoverflow.com/questions/1615472/sparql-negation-all-foafagents-which-arent-foafpersons/1618158
I see. Does bif:exists have a better performance than the “classical” SPARQL 1.0 approach? Because otherwise there is no real advantage in changing the query as using bif:exists is rather complex, too.
bif:exists() may be faster than OPTIONAL… FILTER() or may be slower. When the query is simple enough the optimizer will find full set of possible execution plans for any of these notations and these sets will be identical, so the best plan found will be the same for both variants. When the query is complicated enough (and number of execution plans grow exponentially), the compiler will evaluate some subset of whole set of plans starting from different points (left outer join in case of OPTIONAL…FILTER() and “straightforward” subselect for bif:exists()). Substs will usually intersect and at least some execution plains in the intersection are usually very good, but some plans outside the intersection might be just perfect, so the notation works as a “fine tuning” for the optimizer.
With usual settings, “query is complicated enough” means “one page long” for SPARQL on RDF data or “half page long” for sophisticated SPARQL-BI on RDF Views.