Learning SPARQL

In my post about the future of data.lincoln.ac.uk I committed us to providing a SPARQL endpoint for University of Lincoln open linked data. Today I’ve spent an insane amount of time learning how on earth SPARQL works.

I set up a local triplestore on my laptop using ARC2, I used EasyRDF to output a dump of the staff directory as RDF XML, I used Chris Gutteridge’s Graphite and Browser code to check the EasyRDF output looked right, then finally after I’d loaded the data into the triplestore I used Dave Challis’ SPARQLfront to query the data.

So far I’ve managed to work out the following queries:

(copied from https://gist.github.com/2475211/)


Get all divisions

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

SELECT DISTINCT ?dept ?deptName
WHERE {
  ?dept a org:OrganizationalUnit .
  ?dept rdfs:label ?deptName .
  ?dept org:unitOf <http://lincoln.ac.uk/> .
}

Get all departments in $DIVISION$

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

SELECT DISTINCT ?dept ?deptName
WHERE {
  ?dept a org:OrganizationalUnit .
  ?dept rdfs:label ?deptName .
  ?dept org:unitOf <http://id.online.lincoln.ac.uk/division/$DIVISION$> .
}

Get all staff in $DIVISION$

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

SELECT  ?givenName ?familyName
WHERE {
  ?person a foaf:Person .
  ?person org:memberOf <http://id.online.lincoln.ac.uk/division/$DIVISION$> .
  ?person org:memberOf ?division .
  ?division a org:OrganizationalUnit .
  ?division org:unitOf ?parent .
  ?person foaf:givenName ?givenName .
  ?person foaf:familyName ?familyName .
  FILTER (?parent = "http://lincoln.ac.uk/")
}

Get all staff in $DEPARTMENT$

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

SELECT ?givenName ?familyName
WHERE {
  ?person a foaf:Person .
  ?person org:memberOf <http://id.online.lincoln.ac.uk/department/$DEPARTMENT$> .
  ?person org:memberOf ?division .
  ?division a org:OrganizationalUnit .
  ?division org:unitOf ?parent .
  ?person foaf:givenName ?givenName .
  ?person foaf:familyName ?familyName .
  FILTER (?parent != "http://lincoln.ac.uk/")
}

Get the division that a member of staff is in

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

SELECT ?name
WHERE {
  ?division a org:OrganizationalUnit .
  ?division org:unitOf <http://lincoln.ac.uk/> .
  ?division rdfs:label ?name .
  ?division org:hasMember <http://id.online.lincoln.ac.uk/person/$ID$> .
}

Get the department that a member of staff in is

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX org: <http://www.w3.org/ns/org#>

SELECT ?name
WHERE {
  ?division a org:OrganizationalUnit .
  ?division org:unitOf ?parent .
  ?division rdfs:label ?name .
  ?division org:hasMember <http://id.online.lincoln.ac.uk/person/$ID$> .
  FILTER (?parent != "http://lincoln.ac.uk/")
}

So that is what I’ve worked out so far.

Once I’ve got the final spaces data in the next week or so I’ll figure out some more queries which mix people and spaces.

Some of the resources that I found useful whilst learning SPARQL include:

My thanks also go to Chris Gutteridge, Tony Hirst, Dave Challis, Nicholas J Humfrey, and Benjamin Nowack for their various blog posts and code libraries which I also found useful.