5.2 - Het gebruik van waardelijsten
OVERZICHT
Waardelijsten kunnen voor diverse doeleinden op diverse manieren gebruikt worden. Het eenvoudigst in gebruik zijn conceptwaardelijsten en registerwaardelijsten op peildatum. Registerwaardelijsten compleet bevatten aanzienlijk meer informatie dan hun tegenhangers op peildatum en vragen dus meer inzicht in de gebruikte structuur. De XML-varianten van deze vier waardelijstsoorten bevatten iets minder informatie dan de RDF-varianten. Voor de compleetlijsten is dit verschil nog groter. Voor een bespreking van de XML-structuur en samenhang met de RDF-variant, zie 5.3 - De XML-structuur van XML-waardelijsten. In het hiernavolgende gaan we nader in op de compleetlijsten.
HET GEBRUIK VAN REGISTERWAARDELIJSTEN IN DE COMPLEET-VARIANT
Het gebruik van de registerwaardelijsten in de compleet-variant wordt hierna geïllustreerd
aan de hand van een aantal informatievragen met bijbehorende SPARQL. Deze queries
werken evengoed op de registers zelf. We nemen hierbij steeds de waardelijst https://identifier.overheid.nl/tooi/set/ministerie_compleet/v1.ttl
(met als bestandsnaam ministerie_compleet_v1
) als basis omdat het bronregister zowel relatief klein en handzaam is, en tegelijkertijd
een goed beeld geeft van enerzijds de complexiteit van de modellering, en anderzijds
de rijkdom aan informatie die het beschikbaar maakt. Omdat de waardelijst een afslag
is van het register, richten de vragen zich op het register.
Hoeveel ministerie-objecten bevat het register?
Aantal ministeries
SELECT COUNT(?s)
WHERE {
?s a tooiont:Ministerie .
FILTER NOT EXISTS {?s a tooiont:HistorischeVersie}
}
Deze query retourneert het aantal ministerie-objecten, inclusief ministeries die ooit bestaan hebben maar inmiddels zijn opgeheven. Niet meegeteld worden de historische versies van een ministerie. Bij weglating van het filter zullen ook deze meegeteld worden. Dat is bij deze specifieke informatievraag niet de bedoeling.
Hoe zijn de namen van de ministeries veranderd in de tijd?
Historie van ministerienamen
SELECT ?oc ?org ?t ?hv
WHERE {
[] a tooiont:Toestandswijziging ;
prov:used / tooiont:afkorting ?org ;
prov:used / tooiont:organisatiecode ?oc ;
tooiont:tijdstipWijziging ?t ;
prov:invalidated / tooiont:afkorting ?hv .
} ORDER BY ?org
Deze querie selecteert alle toestandswijzigingen, en bij elk van deze de huidige (of
laatst bekende) afgekorte naam en de organisatiecode van organisatie waar de toestandsverandering
betrekking op heett (prov:used
), het tijdstip van wijziging, en de afgekorte naam die hoort bij de toestand die
na de wijziging niet meer van kracht was (prov:invalidated
). Het resultaat van deze query is (gegeven de (versie van de) genoemde waardelijst):
Organisatiecode | Ministerie | Tijdstip wijziging | Oude naam |
mnre1045 | EZK | 2018-01-01T00:00:00 | EZ |
mnre1045 | EZK | 2013-01-01T00:00:00 | ELenI |
mnre1130 | IenW | 2018-01-01T00:00:00 | IenM |
mnre1058 | JenV | 2010-12-01T00:00:00 | MinJus |
mnre1058 | JenV | 2018-01-01T00:00:00 | VenJ |
Dit dient als volgt gelezen te worden: JenV heette tot 1 december 2010 MinJus, en tot 1 januari 2018 heette het VenJ. Merk op dat de waarden in de eerste kolom onveranderlijk zijn. Immers, een andere organisatiecode zou een andere URI betekenen — en dat betekent een andere identiteit. De afkortingen in de tweede kolom staan voor de naam van het ministerie op de peildatum van de waardelijst. Die naam verandert door de tijd.
Welke ministeries hebben door de tijd heen bestaan?
Om te bekijken welke ministeries door de tijd heen opgericht en eventueel weer opgeheven
zijn, zoeken we alle instanties van tooiont:ExistentieleWijziging
op. Deze gaan terug tot 2010; ministeries die daarvoor zijn opgeheven of opgericht
(zonder na 2010 opgeheven te zijn) worden met deze query dus niet gevonden. Bij elke
instantie sommen we de organisaties op die opgeheven zijn (prov:invalidated
) en de organisaties die opgericht zijn (prov:generated
) als gevolg van de wijziging. Omdat een existentiële wijziging nul of meerdere van
elk kan hebben gebruiken we de union van twee aparte graph patterns.
Organisaties die bestaan of bestaan hebben
SELECT ?w ?type ?datum ?inv ?gen
WHERE {
{
?w rdf:type / rdfs:subClassOf tooiont:ExistentieleWijziging ;
a ?type ;
tooiont:tijdstipWijziging ?t ;
prov:invalidated / tooiont:afkorting ?inv .
BIND (xsd:date(?t) AS ?datum )
} UNION {
?w rdf:type / rdfs:subClassOf tooiont:ExistentieleWijziging ;
a ?type ;
tooiont:tijdstipWijziging ?t ;
prov:generated / tooiont:afkorting ?gen .
BIND (xsd:date(?t) AS ?datum )
}
}
De query geeft het volgende resultaat:
Wijziging | Type wijziging | Datum | Beeindigd | Gestart |
---|---|---|---|---|
ministerie:wzg_00926444 |
tooiont:Samenvoeging |
14/10/2010 | VROM | |
ministerie:wzg_00926444 |
tooiont:Samenvoeging |
14/10/2010 | VW | |
ministerie:wzg_00926444 |
tooiont:Samenvoeging |
14/10/2010 | IenW | |
ministerie:wzg_01378363 |
tooiont:Afsplitsing |
26/10/2017 | LNV | |
ministerie:wzg_06434036 |
tooiont:Samenvoeging |
14/10/2010 | LNV | |
ministerie:wzg_06434036 |
tooiont:Samenvoeging |
14/10/2010 | EZ | |
ministerie:wzg_06434036 |
tooiont:Samenvoeging |
14/10/2010 | EZK |
Dit moet gelezen worden als: er was een samenvoeging op 14 oktober 2010, en als gevolg daarvan zijn VROM en VW (Verkeer en Waterstaat) opgeheven, en is IenW gestart. Merk op dat hierbij de afkortingen gebruikt worden die nu nog geldig zijn, of geldig waren op het moment van opheffen. Voor IenW geldt bijvoorbeeld dat op het moment van oprichting nog MinIenM heette.
Welke ministeries waren met welke naamgeving geldig op peildatum 2 september 2010?
Het kan heel nuttig zijn om organisaties die op een peildatum bestonden uit te vragen,
met de naam die op die datum geldig waren. In dit specifieke voorbeeld is het nodig
bij elk relevant ministerie de historische versies te vinden (voor zover aanwezig),
en daaruit de versie te selecteren die op de peildatum geldig was. Bij het selecteren
van de ministeries die bestonden op de peildatum moeten we rekening houden met het
feit dat de properties prov:generatedAtTime
en prov:invalidatedAtTime
voor een gegeven ministerie in voorkomende gevallen ongespcificeerd kunnen zijn.
De waarde van prov:generatedAtTime
(?gt) kan eenvoudig onbekend zijn. Als de waarde van prov:invalidatedAt
(?it) niet is gespecificeerd, dan betekent dat dat het ministerie nog bestaat. Er zijn
dus vier mogelijkheden. Om de zaak te vereenvoudigen definiëren we twee variabelen,
?start en ?end, die we gelijk stellen aan ?gt en ?it als deze gespecificeerd zijn. Zo niet, dan geven we ze een waarde in het verre verleden
of de verre toekomst (regel 9 en 10). Vervolgens filteren we alle ministeries weg
die op de peildatum nog niet of niet meer bestonden (regel 11 en 12).
Wat volgt is een geneste query van twee niveaus diep om de historische versies te vinden en daaruit de juiste te selecteren.
Welke organisaties bestonden er op een peildatum
SELECT ?org ?naamGeldigOpPeildatum
WHERE {
BIND ( ("2010-09-02T00:00:00"^^xsd:dateTime) AS ?peildatum ) .
?org a tooiont:Ministerie ;
rdfs:label ?label .
FILTER NOT EXISTS { ?org a tooiont:HistorischeVersie }
OPTIONAL { ?org prov:generatedAtTime ?gt }
OPTIONAL { ?org prov:invalidatedAtTime ?it }
BIND ( (IF (bound(?gt), ?gt, "1800-01-01T00:00:00"^^xsd:dateTime)) AS ?start )
BIND ( (IF (bound(?it), ?it, "2100-01-01T00:00:00"^^xsd:dateTime)) AS ?end )
FILTER (?start < ?peildatum )
FILTER (?end > ?peildatum )
OPTIONAL {
SELECT ?org ?naam
WHERE {
{
SELECT ?org ( MIN( ?eindeGeldigheidVanToestand ) AS ?e )
WHERE {
BIND ( ("2010-09-02T00:00:00"^^xsd:dateTime) AS ?peildatum ) .
?tw a tooiont:Toestandswijziging ;
prov:used ?org ;
tooiont:tijdstipWijziging ?eindeGeldigheidVanToestand ;
.
FILTER (?eindeGeldigheidVanToestand > ?peildatum)
} GROUP BY ?org HAVING BOUND(?org) ## Filter met HAVING nodig wegens RDF4J-bug
}
?tw2 a tooiont:Toestandswijziging .
?tw2 prov:used ?org .
?tw2 tooiont:tijdstipWijziging ?e .
?tw2 prov:invalidated / rdfs:label ?naam .
}
}
BIND ( (IF (bound(?naam), ?naam, ?label)) AS ?naamGeldigOpPeildatum )
}
Het resultaat van deze query is als volgt:
URI | Naam geldig op 2 september 2010 |
ministerie:mnre0170 |
ministerie van Verkeer en Waterstaat |
ministerie:mnre0180 |
ministerie van Volkshuisvesting, Ruimtelijke Ordening en Milieubeheer |
ministerie:mnre1010 |
ministerie van Algemene Zaken |
ministerie:mnre1013 |
ministerie van Buitenlandse Zaken |
ministerie:mnre1018 |
ministerie van Defensie |
ministerie:mnre1025 |
ministerie van Volksgezondheid, Welzijn en Sport |
ministerie:mnre1034 |
ministerie van Binnenlandse Zaken en Koninkrijksrelaties |
ministerie:mnre1040 |
ministerie van Economische Zaken |
ministerie:mnre1058 |
ministerie van Justitie |
ministerie:mnre1073 |
ministerie van Sociale Zaken en Werkgelegenheid |
ministerie:mnre1090 |
ministerie van Financiën |
ministerie:mnre1109 |
ministerie van Onderwijs, Cultuur en Wetenschap |
ministerie:mnre1150 |
ministerie van Landbouw, Natuur en Voedselkwaliteit |
Het doel van de OPTIONAL-groep is om een eventuele historische versie van een ministerie die geldig was op de peildatum te vinden. Zo ja, dan wordt de naam van die historische versie in het resultaat verwerkt. Zo niet, dan nemen we de naam van het ministerie die op het moment van uitvoering van de querie geldig is. Dat gebeurt op regel 34.
We bekijken nu een vereenvoudigde versie van de diepst geneste query. Deze vind per ministerie de bijbehorende toestandswijzigingen en het tijdstip van wijziging:
Vereenvoudigde inner query
SELECT ?org ?tw ?eindeGeldigheidVanToestand
WHERE {
?tw a tooiont:Toestandswijziging ;
prov:used ?org ;
tooiont:tijdstipWijziging ?eindeGeldigheidVanToestand ;
.
}
Dit levert de volgende resultaten op:
Ministerie | Toestandswijziging | Tijdstip |
ministerie:mnre1045 |
ministerie:wzg_80272410 |
2013-01-01T00:00:00 |
ministerie:mnre1045 |
ministerie:wzg_17545147 |
2018-01-01T00:00:00 |
ministerie:mnre1058 |
ministerie:wzg_05229330 |
2018-01-01T00:00:00 |
ministerie:mnre1058 |
ministerie:wzg_00821007 |
2010-12-01T00:00:00 |
ministerie:mnre1130 |
ministerie:wzg_08160830 |
2018-01-01T00:00:00 |
We nesten deze query om per ministerie alleen de oudst geregistreerde toestandswijziging te vinden.
Geneste query
SELECT ?org ?e ?tw2 ?naam
WHERE {
{
SELECT ?org ( MIN( ?eindeGeldigheidVanToestand ) AS ?e )
WHERE {
?tw a tooiont:Toestandswijziging ;
prov:used ?org ;
tooiont:tijdstipWijziging ?eindeGeldigheidVanToestand ;
.
} GROUP BY ?org HAVING BOUND(?org) ## Filter met HAVING nodig wegens RDF4J-bug
}
?tw2 prov:used ?org ;
tooiont:tijdstipWijziging ?e ;
prov:invalidated / rdfs:label ?naam ;
.
}
Deze geeft de volgende resultaten:
Ministerie | Tijdstip wijziging | Toestandswijziging | Naam geldig in de toestand vóór wijziging |
ministerie:mnre1045 |
2013-01-01T00:00:00 |
ministerie:wzg_80272410 |
ministerie van Economische Zaken, Landbouw en Innovatie |
ministerie:mnre1058 |
2010-12-01T00:00:00 |
ministerie:wzg_00821007 |
ministerie van Justitie |
ministerie:mnre1130 |
2018-01-01T00:00:00 |
ministerie:wzg_08160830 |
ministerie van Infrastructuur en Milieu |
De binnenste query geeft de eerste twee kolommen van deze tabel. De resultaatset wordt gejoind met de resultaten van de buitenste query. Daarmee worden de laatste twee kolomen gevonden. Met een paar kleine aanpassingen kunnen we dit in de hoofdquery plakken, binnen de OPTIONAL-groep. In de binnenste query voegen we een filter op peildatum toe. Daartoe moeten we de peildatum nog een keer toekennen: SPARQL query-evaluatie werkt van binnen naar buiten. Buiten de OPTIONAL-groep, op regel 34, wordt getest of er voor het betreffende ministerie een historische naam is gevonden. Die kennen we dan toe aan het resultaat. Zo niet, dan gebruiken we de naam van het ministerie.
Wanneer we ervoor zouden kiezen bij de de historische versie-objecten een startmoment en eindmoment toe te voegen, dan zou de hoofdquery aanzienlijk eenvoudiger zijn. De OPTIONAL-groep ziet er dan als volgt uit:
Het OPTIONAL gedeelte
OPTIONAL {
?tw a tooiont:Toestandswijziging .
?tw prov:used ?org .
?tw prov:invalidated / prov:invalidatedAtTime ?e .
?tw prov:invalidated / prov:generatedAtTime ?b .
?tw prov:invalidated / rdfs:label ?naam .
FILTER (?b < ?peildatum)
FILTER (?e > ?peildatum)
}
Het voordeel van eenvoudig te begrijpen queries gaat echter ten koste van de eenvoud van de data. Het opslaan van veel redundante gegevens maakt data-entry foutgevoelig. Een klein foutje bij de bron of in de verwerkende software kan moeilijk te vinden en lastig te repareren problemen in de data opleveren. We hebben daarom gekozen voor eenvoud in de data.