Tutorial: SPARQL bevragingstaal

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:

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?

Je kunt dit deel van de tutorial ook als video bekijken.

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

Je kunt dit deel van de tutorial ook als video bekijken.

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 naar sor:Woonplaats gebruik maakt van de sor: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.