SPARQL Recipes

From n² wiki

Jump to: navigation, search


Contents

[edit] Finding Resources that don't have a certain property

To retrieve resources that don't have the ex:foo property, make that property OPTIONAL, and then FILTER in all resources where that property isn't bound.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

DESCRIBE ?s
WHERE 
{
?s ?p ?o .
OPTIONAL 
{
  ?s rdf:type ?Thing .
}
FILTER (!bound(?Thing)) 
}

[edit] FILTERing in literals with a given language OR no language at all

Often you want to filter out results with a different language from the one you want, but you want to leave in results that don't have a language type specified.

FILTER(langMatches(lang(?o),'en-gb')||(!langMatches(lang(?o),'*')))

[edit] Retrieving Resources with the same value for a given predicate

DESCRIBE ?a ?b
WHERE 
{ 
	?a foaf:mbox ?join . 
        ?b foaf:mbox ?join . 
	
     FILTER(?a != ?b)
}
LIMIT 2

The thing to remember is that you need to ensure that ?a and ?b aren't the same resource, otherwise you will get an unpredictable number of results - if ?a were to be the same as ?b, it would only occur once in the results of a DESCRIBE or CONSTRUCT

[edit] MAX and MIN

(from http://dallemang.typepad.com/my_weblog/2007/09/min-and-max-in-.html )

SELECT DISTINCT  ?label ?by

WHERE {?kennedy a :Person .

       ?kennedy  rdfs:label  ?label .

       ?kennedy :birth-year ?by .

       OPTIONAL {?older a :Person .

                 ?older :birth-year ?oby .

                 FILTER (?oby < ?by)}

       FILTER (!bound (?older))

}

How does this work? The first three triples match any member of the family for which a birth year is known. The pattern inside the OPTIONAL clause also matches a family member, and gets their birth year. We use the variable name ?older for this person because of the FILTER clause; we retain only the bindings of ?older that have an earlier birth year than ?kennedy. Now here's how we get a max out of this: what happens if we can't find anyone with an earlier birth year? Then all matches to the pattern inside the OPTIONAL braces will be filtered out, and no bindings will remain for ?older. Back outside the OPTIONAL, we filter based on the binding of ?older; if ?older is not bound, then we didn't find anyone with an earlier birth year. Who is the person for whom nobody else has an earlier birth year? That's the oldest, of course.

[edit] Performance

[edit] Order of query

Put the most restrictive clauses first in the query. eg, if many resources have dc:title, but far fewer have foaf:mbox, and you want to find resources with a dc:title and a foaf:mbox, then do:

?x foaf:mbox ?mbox ;
   dc:title ?title .

not

?x  dc:title ?title ;
    foaf:mbox ?mbox .

[edit] Variable Predicates

Avoid using variables in the predicate position if you can help it, as it may slow down the query, and in some cases greatly bloat the result set.

[edit] Tips

Exploratory SPARQL

You can do

DESCRIBE ?s WHERE { 
    ?s ?p ?o 
} 
LIMIT 20 

to just get a bunch of random descriptions, and work from there, perhaps with a

FILTER(REGEX(?o, "some keyword"))

You could also do

SELECT DISTINCT ?type WHERE { 
  ?s a ?type 
} 
LIMIT 20 

to get back a list of class types used in a store - or

ASK WHERE { ?s <somepredicate> ?o  } 

to find out if a particular predicate is used in the store.

Unfortunately, sparql doesn't scale that well on large stores, such as schema-cache on the Talis Platform, so you may find that at least the first two of those queries simply time out before you get any results (we are working on making this better though!)

Personal tools