LODUM by Example

For most of the LODUM team members, the SPARQL by example tutorial provided by Cambridge Semantics was immensely useful when we wrote our first SPARQL queries. So, why not provide a similar tutorial, focusing on the LODUM data?

We hope that the following list of sample queries makes the learning curve a little less steep for developers who are new to LODUM and/or querying RDF data in general. Each query can be executed and modified by clicking on the title, which will take you to our SPARQL editor, pre-filled with the query. Just edit and customize the examples and see what happens. Happy querying!

Find URI of Person

prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
 
SELECT ?person WHERE {
?person foaf:name "Trame, Johannes"^^xsd:string.
?person rdf:type foaf:Person.
}


Search for a Person by Keyword

prefix foaf: <http://xmlns.com/foaf/0.1/>
 
SELECT ?name ?person WHERE {
?person foaf:name ?name;
a foaf:Person.
FILTER regex(?name,"kuhn","i").
}

The predicate a is a short form for rdf:type. The line FILTER regex(?name,"kuhn","i") has the effect that only those graph patterns are chosen, in which the string variable ?name contains the string "kuhn". The tag "i" makes the regular expression filter case-insensitive. Omission of this tag creates a case-sensitive filter, for example FILTER regex(?name,"Kuhn").

Find all Publications (Including URI, Title and Year) of a Person, Sorted by Year

prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix dct: <http://purl.org/dc/terms/>
prefix bibo: <http://purl.org/ontology/bibo/>
prefix foaf: <http://xmlns.com/foaf/0.1/>
 
SELECT ?pub ?title ?year WHERE {
"Kuhn, Werner"^^xsd:string ^foaf:name ?person.
?pub bibo:producer ?person;
dct:title ?title;
dct:issued ?year.
}
ORDER BY DESC(?year)

A ^-symbol in front of the predicate turns around its direction, i.e. the syntax ?a ^foaf:name ?b. is equivalent to ?b foaf:name ?a. The ORDER BY ?x command orders the results of the query by the variable ?x. ORDER BY DESC(?x) would sort the results in descending order.

Find Distinct Names of All Co-Authors of a Person

prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix bibo: <http://purl.org/ontology/bibo/>
prefix foaf: <http://xmlns.com/foaf/0.1/>
 
SELECT DISTINCT ?coauthorname WHERE {
?person foaf:name "Kuhn, Werner"^^xsd:string.
?pub bibo:producer ?person,?coauthor.
?coauthor foaf:name ?coauthorname.
}
ORDER BY ?coauthorname

Using DISTINCT has the effect that each result in the output appears only once, i.e. there are no repetitions in the output, even if the pattern can be found more than once.

Find All Distinct Names of Coauthors of a Person (Excluding That Person’s Own Name)

prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix bibo: <http://purl.org/ontology/bibo/>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix lodum:<http://vocab.lodum.de/helper/>
 
SELECT DISTINCT ?coauthorname WHERE {
?person foaf:name "Kuhn, Werner"^^xsd:string;
lodum:personID ?person_id.
?pub bibo:producer ?person,?coauthor.
?coauthor foaf:name ?coauthorname;
lodum:personID ?coauthor_id.
FILTER(?person_id!=?coauthor_id).
}

Each person stored in the LODUM triple store, i.e. each entity of type foaf:Person, is assigned a unique ID number (inherited from the university’s CRIS research database). The condition FILTER(?person_id!=?coauthor_id) selects only those grpah patterns where the ?person and ?coauthor have different IDs.


Find Title and Year of Coauthors’ Publications (Limited to 100 Results, Ordered by Issued Year)

prefix xsd: <http://www.w3.org/2001/XMLSchema#> 
prefix dct: <http://purl.org/dc/terms/>
prefix bibo: <http://purl.org/ontology/bibo/>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix lodum:<http://vocab.lodum.de/helper/>
 
SELECT DISTINCT ?title ?publication ?year WHERE {
?person foaf:name "Kuhn, Werner"^^xsd:string; lodum:personID ?pID.
?pub bibo:producer ?person,?coauthor .
?coauthor foaf:name ?coauthorname; lodum:personID ?cID.
FILTER (?cID!=?pID).
?pubco bibo:producer ?coauthor;
dct:title ?title;
dct:issued ?year.
BIND(?pubco AS ?publication).
} ORDER BY DESC(?year)
LIMIT 100

The function BIND(?pubco AS ?publication) creates a variable ?publication which is the assigned the same value as ?pubco. LIMIT 100 limits the output to the first 100 results.


Find All RDF Triples That Contain a Particular Person as Subject or Object

prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix lodum:<http://vocab.lodum.de/helper/>
 
SELECT DISTINCT ?name (?p AS ?property) (?q AS ?isPropertyOf) (?v AS ?value)
WHERE{
?x a foaf:Person; lodum:personID "9325"; foaf:name ?name.
{?x ?p ?v.}UNION{?v ?q ?x.}
}

Instead of using the BIND function, renaming variables can be done before the WHERE-statement. This can be useful to avoid long variable names in the body of the query. Combining two graph patterns with {...}UNION{...} in a query returns all results matching either of the graph patterns.

Find Names of Distinct Organizations (and Their Websites) Concerned with Economics

prefix foaf: <http://xmlns.com/foaf/0.1/>
 
SELECT DISTINCT (?c AS ?organization) (?n AS ?name) (?h AS ?homepage) WHERE{
?c a foaf:Organization; foaf:name ?n.
OPTIONAL{?c foaf:homepage ?h.}
{FILTER regex(?n, "wirtschaft", "i").}UNION{FILTER regex(?n, "econom", "i").}UNION
{FILTER regex(?n, "ökonom", "i").}
}
ORDER BY ?name

Graph patterns enclosed in the brackets of OPTIONAL{...} do not have to be fulfilled by all the results of the query (i.e., they are optional – hence the name).

Find Distinct English Names of all Departments

prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix lodum:<http://vocab.lodum.de/helper/>
 
SELECT DISTINCT (?c AS ?department) WHERE{
?c ^foaf:name/a lodum:Department.
FILTER langmatches(lang(?c),"EN").
}
ORDER BY ?department

The syntax ?c ^foaf:name/a lodum:Department. is a short form of ?c ^foaf:name ?x. ?x a lodum:Department.
The second line FILTER langmatches(lang(?c),"EN"). selects those results where ?c has the language “EN”.

Find the Names of All Departments Including Links to Their Data Sites

prefix foaf: <http://xmlns.com/foaf/0.1/>
PREFIX lodum:<http://vocab.lodum.de/helper/>
 
sEleCt DiStiNct (?e as $department_en) (?d as ?department_de) ($x AS ?link) where{
?x a lodum:Department; foaf:name $e,$d.
FIltER langmatches(lang(?e),"En").
fiLTer langmatches(lang($d),"dE").
}
order by ?department

This query shows that much of the SPARQL syntax is not case sensitive, and also that for defining variables the symbol $ can be used instead of ?.

Find All Entities Belonging to the University Located at ‘Schlossplatz’ (plus Websites & Addresses)

prefix foaf: <http://xmlns.com/foaf/0.1/> 
prefix vcard:<http://www.w3.org/2006/vcard/ns#>
 
SELECT DISTINCT ?thing (?h as ?homepage) ?adress WHERE{
?x vcard:adr ?adress;
foaf:name ?thing.
{?x foaf:homepage ?h.}UNION
{
MINUS{?x foaf:homepage ?g.}
BIND(?x as ?h).
}
FILTER regex(?adress, "Schlossplatz").
}
ORDER BY ?thing

Using MINUS{...} specifies a graph pattern which the results are not allowed to fulfill.
This query diplays the homepage if it exists, otherwise it shows the data site.

Find All Canteens (Mensa, Bistro) Run by the Uni Münster

prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix vcard:<http://www.w3.org/2006/vcard/ns#>
prefix db_ont: <http://dbpedia.org/ontology/>
prefix lodum: <http://vocab.lodum.de/helper/>
 
SELECT DISTINCT (?c as?canteen) (?a as ?adress) (?l as ?location_map) WHERE {
?x a db_ont:Restaurant;
foaf:name ?c;
vcard:adr ?a;
lodum:building ?l.
}
ORDER BY ?c

Find the Canteen Offering for the Next Days

prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix db_ont: <http://dbpedia.org/ontology/>
prefix gr: <http://purl.org/goodrelations/v1#>
 
SELECT DISTINCT ?canteen ?food ?start ?end ?min_price ?max_price
WHERE{
?o a gr:Offering; ^gr:offers ?res.
?res a db_ont:Restaurant; foaf:name ?canteen.
?o gr:name ?food;
gr:availabilityStarts ?start;
gr:availabilityEnds ?end;
gr:hasPriceSpecification ?price.
?price gr:hasCurrency ?cur; gr:hasMinCurrencyValue ?min; gr:hasMaxCurrencyValue ?max.
bind(concat(?min," ", ?cur) as ?min_price).
bind(concat(?max," ", ?cur) as ?max_price).
filter(?end >= now() ).
}
ORDER BY ?start ?canteen

The expression concat(.. , .. , .. , ..) concatenates many strings to another string.
The function now() returns the current time and date, as you can see here.

Of course, there are always several ways to get to the same results. So if you find any cool queries or discover a more efficient version of a query, please drop us a line.

This is a post
on the LODUM blog.


Add a comment

Required

Required, but won't be shown

Optional