
Introductie
In dit onderdeel van de tutorial maken we je wegwijs in de SPARQL bevragingstaal. Hiermee kun je snel je eerste queries uitvoeren.
Overzicht
Deze tutorial is de derde in een reeks, bestaande uit de volgende delen:
- Stap 0 - Introductie
- Stap 1 - Exploreer het datamodel
- Stap 2 - SPARQL bevragingstaal (dit artikel)
- Stap 3 - Registratie vs. Knowledge Graph
- Stap 4 - Gebruik van eigen programmeertaal
Doel van deze module
Na deze module kun je aan je collega's uitleggen:
- Hoe je een SPARQL bevraging kunt uitvoeren.
- Hoe je een SPARQL bevraging kunt aanpassen.
- Hoe je een SPARQL bevraging kunt opbouwen.
Voordat je begint
Gedurende deze module zullen we verschillende queries uitoefenen met SPARQL op de Kadaster Knowledge Graph. Om deze query te versturen gebruiken we het SPARQL API endpoint van de KKG: link. De queries die als voorbeeld op deze pagina zijn opgenomen zijn in te zien en aan te passen door op de "Try this query yourself" link te klikken.
I. Wat is SPARQL?
SPARQL is de standaard taal voor het bevragen van Resource Description Framework (RDF) data. De standaard wordt beheerd door het W3C en is een onmisbaar onderdeel van Linked Data. Voor een volledige overzicht in de volledige SPARQL query language raden we de gebruiker aan die standaard dan ook eens rustig door te lezen. In deze tutorial leren we je echter de basis waarmee je je eerste selectie en combinatie vraag kan stellen aan de Kadaster datasets.
Laten we met een simpele query beginnen. We willen graag iedere triple opvragen die de waarde "Apeldoorn"
als literal bevat. Omdat dit een Nederlandse string is, dienen we aan het einde van deze string een language tag mee te geven (@nl
).
select ?subject ?predikaat {
?subject ?predikaat 'Apeldoorn'@nl.
}
limit 10
Wat je terugkrijgt zijn verschillende IRIs voor entiteiten die 'Apeldoorn' heten. Sommige van deze entiteiten gebruiken rdfs:label
en sommige gebruiken skos:prefLabel
om deze relatie mee aan te duiden. Wat opvalt is dat in deze resultaten alleen IRIs terugkomen. Alhoewel dit gewenst gedrag is vanuit een linked data perspectief, maakt het de resultaten wel lastig te lezen. Om die reden staat SPARQL toe om bepaalde prefixes toe te voegen aan je bevraging. Deze worden toegevoegd met het prefix
keyword in de SPARQL taal. In de volgende query wordt de SKOS prefix gebruikt om de prikaat term expliciet op te geven, hierdoor worden de resultaten die rdfs:label
gebruiken niet langer meer teruggegeven.
prefix skos: <http://www.w3.org/2004/02/skos/core#>
select ?subject {
?subject skos:prefLabel 'Apeldoorn'@nl.
}
limit 10
De Kadaster Knowledge Graph maakt gebruik van verschillende vocabulaires in het data model. De meeste termen komen uit de Samenhangende Objecten Registratie (SOR), met prefix sor
. Een voorbeeld van een klasse term is sor:Woonplaats
; een voorbeeld van een eigenschap term is sor:postcode
.
Uitdaging 1 Kun jij nu ook alle triples opvragen met een postcode gelijk aan
'2513AA'
en daarmee het Torentje van de premier vinden?
II. Klassen en meerdere eigenschappen
Er is een speciale eigenschap die instanties aan klassen verbindt. Met deze eigenschappen kunnen we bijvoorbeeld alle woonplaatsen (sor:Woonplaats
) ophalen. Deze eigenschap is zo fundamenteel voor linked data dat deze onderdeel uitmaakt van het standaard RDF vocabulaire (prefix rdf:
). Deze eigenschap is rdf:type
. In SPARQL kan deze eigenschap bovendien worden afgekort tot de letter a
.
Een andere afkorting die we vaak toepassen is de puntkomma (;
). Deze geeft aan dat de subject term (in de volgende query: ?woonplaats
) impliciet herhaalt wordt in het volgende triple patroon. Als we de puntkomma niet gebruiken zouden we nodeloos vaak dezelfde variabele naam moeten herhalen. Wanneer de subject term niet meer herhaald hoeft te worden kunnen we een triple patroon afsluiten met een punt (.
).
In de volgende query sommen we een aantal woonplaatsen op, samen met hun naam en status. Merk op dat deze status gebruik maakt van het Kadaster data model (prefix kad-con:
) en dat de waarde altijd 'woonplaats aangewezen' is. Dit komt doordat de KKG alleen actuele gegevens bevat (en dus geen teruggetrokken woonplaatsen bevat).
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix sor: <https://data.kkg.kadaster.nl/sor/model/def/>
select * {
?woonplaats
a sor:Woonplaats;
skos:prefLabel ?naam;
sor:status ?status;
}
limit 10
Uitdaging 2: Kun jij nu ook alle verblijfsobjecten (
sor:Verblijfsobject
) vinden die een nevenadres (sor:nevenadres
) hebben?
III. Relaties tussen objecten
Nu we een selectie hebben gemaakt voor woonplaatsen, en we weten hoe we met historie om moeten gaan, willen we additionele relaties leggen. Kunnen we bijvoorbeeld alle straten in Apeldoorn ophalen?
- In het data model (denk aan de eerdere tutorial) is te zien dat de relatie van
sor:OpenbareruimteRegistratie
naarsor:Woonplaats
gebruik maakt van desor:ligtIn
eigenschap. - Door de IRIs te dereferencen in web browser kunnen we alle eigenschappen van instanties inzien. Bijvoorbeeld deze IRI: https://data.kkg.kadaster.nl/id/woonplaats/3560.
- Merk op dat we steeds het aantal resultaten limiteren (
limit 10
). Voor deze bevraging is dat voldoende. Het SPARQL endpoint geeft standaard maximaal 10.000 resultaten terug. In het geval van meer dan 10K resultaten kan gebruiken gemaakt worden van SPARQL paginatie om alle resultaten op te halen.
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix sor: <https://data.kkg.kadaster.nl/sor/model/def/>
select * {
?woonplaats
a sor:Woonplaats;
skos:prefLabel 'Apeldoorn'@nl.
?openbareruimte
a sor:OpenbareRuimte;
skos:prefLabel ?openbareruimteNaam;
sor:ligtIn ?woonplaats.
}
limit 10
Uitdaging 3: Kun jij naast woonplaats ook nog een ander soort object vinden dat in relatie staat tot een openbare ruimte?
Meer objecten en wisselende granulariteit
In bovenstaand voorbeeld maakten we slechts gebruik van twee verschillende soorten objecten (openbare ruimten en woonplaatsen). Zoals we in het data model kunnen zien bevat de KKG een groot aantal andere typen objecten. We hebben meer object typen nodig om een brief te kunnen versturen met de juiste adresgegevens. We hebben hiervoor de volgende informatie nodig:
- Huisnummer
- Huisletter (indien aanwezig)
- Huisnummertoevoeging (indien aanwezig)
- Postcode
- Straatnaam (openbare ruimte naam)
- Woonplaatsnaam
Hiervoor hebben we een aantal nieuwe SPARQL functionaliteiten nodig:
- Voor de optionele eigenschappen moeten we keyword
optional
gebruiken. - Een openbare ruimte ligt in een woonplaats, en die woonplaats heeft een naam. Als we vanuit een openbare ruimte direct naar de naam van de woonplaats willen gaan kunnen we slash (
/
) gebruiken om twee (of meer) eigenschappen achter elkaar te plaatsen.
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix sor: <https://data.kkg.kadaster.nl/sor/model/def/>
select * {
?nummeraanduiding
a sor:Nummeraanduiding;
sor:postcode '1011AB';
sor:huisnummer ?huisnummer;
sor:ligtAan ?openbareRuimte.
optional { ?nummeraanduiding sor:huisletter ?huisletter. }
optional { ?nummeraanduiding sor:huisnummertoevoeging ?huisnummertoevoeging. }
?openbareRuimte
a sor:OpenbareRuimte;
skos:prefLabel ?straatnaam;
sor:ligtIn/skos:prefLabel ?woonplaatsnaam.
}
limit 100
Adressen van kantoren (gebruiksdoel)
Met bovenstaande bevraging kunnen we adresgegevens ophalen. Maar stel nu dat we alleen brieven willen versturen naar kantoorruimten (en niet naar bijvoorbeeld woonhuizen). Hiervoor moeten we het gebruiksdoel (sor:gebruiksdoel
) weten. Dit is een eigenschap van een verblijfsruimte (sor:Verblijfsruimte
).
Omdat we de verblijfsruimte zelf nergens voor gebruiken hoeven we geen variabele ?verblijfsobject
te gebruiken. We kunnen in plaats van een variabele naam de blokhaken ([]
) opgeven.
De volgende bevragen voegt de volgende regels toe aan de vorige bevraging:
[] a sor:Verblijfsobject;
sor:hoofdadres ?nummeraanduiding;
sor:gebruiksdoel ?gebruiksdoel.
Merk op dat we verschillende waardes voor ?gebruiksdoel
terug krijgen. Door de variabele ?gebruiksdoel
te vervangen door de term sor-con:kantoorfunctie
krijgen we alleen de adresgegevens voor kantoorruimten terug.
We hebben nu de noodzakelijke deelgegevens voor een adres, maar dat is nog niet hetzelfde als een mooie leesbare adresregel. Met keyword bind
kunnen we een nieuwe variabele in een SPARQL query introduceren. Met behulp van verschillende SPARQL functies kunnen we zo een adresregel opbouwen. Om een mooi overzicht van de adresregels te krijgen gebruiken we order by ?adresregel
.
Merk op dat we inmiddels een flinke query geschreven hebben. Maar merk ook op dat we met deze query al dicht in de buurt van nuttige toepassingen komen.
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix sor: <https://data.kkg.kadaster.nl/sor/model/def/>
prefix sor-con: <https://data.kkg.kadaster.nl/sor/model/con/>
select ?adresregel {
?nummeraanduiding
a sor:Nummeraanduiding;
sor:postcode '1011AB';
sor:huisnummer ?huisnummer;
sor:ligtAan ?openbareRuimte.
optional { ?nummeraanduiding sor:huisletter ?huisletter. }
optional { ?nummeraanduiding sor:huisnummertoevoeging ?huisnummertoevoeging. }
?openbareRuimte
a sor:OpenbareRuimte;
skos:prefLabel ?straatnaam;
sor:ligtIn/skos:prefLabel ?woonplaatsnaam.
[] a sor:Verblijfsobject;
sor:hoofdadres ?nummeraanduiding;
sor:gebruiksdoel sor-con:kantoorfunctie.
bind(concat(
str(?straatnaam),' ',str(?huisnummer),
if(bound(?huisletter),?huisletter,''),
if(bound(?huisnummertoevoeging),concat('-',?huisnummertoevoeging),''),
', ',?postcode,' ',str(?woonplaatsnaam)) as ?adresregel)
}
order by ?adresregel
limit 100
Geometrische bevragingen
Bij geografische datasets is het vaak van belang om de geometrieën van de verschillende objecten op te halen. In de Kadaster Knowledge Graph wordt GeoSPARQL (prefix geo:
) gebruikt om dergelijke geografische informatie op te slaan. Met het volgende eigenschappen pad wordt deze informatie opgehaald:
geo:hasGeometry/geo:asWKT
Meervoudige informatie
Soms is hetzelfde gegeven in meerdere varianten beschikbaar. Een voorbeeld hiervan in de Kadaster Knowledge Graph is de geometrie. Gebouwen hebben bijvoorbeeld meerdere geometrie gegeven, die elk op een andere wijze zijn ingewonnen.