Zo werken SPARQL-queries op Wikidata
Eerder schreef ik hier over Depictor. Dat is mijn tooltje om foto’s te taggen op Wikimedia Commons , de mediabank van de Wikimedia-projecten zoals Wikipedia. Ik schreef toen over één van de opties in dat tooltje: het toevoegen van een SPARQL-query als zoekvraag. Én ik schreef dat het te ingewikkeld was om snel uit te leggen wat SPARQL is.
Nou, dat heb ik geweten. Een paar lezers mailden me: kun je het misschien tóch uitleggen, en dan iets minder snel? Ik stuurde die mensen een uitleg terug, maar het leek me eigenlijk wel handig om dat toch ook maar hier op te schrijven. Dan kunnen mensen het ook lezen die me niet mailen. Zoals jij!
Samengevat is SPARQL een taal waar je zoekvragen mee kan schrijven om gelinkte data uit een systeem (zoals Wikidata) te halen. Eigenlijk dus een soort van Google, maar dan voor gevorderden.
Laat ik een voorbeeld geven. Koning Willem-Alexander heeft een plekje op Wikidata. Alleen dan niet met een artikel maar met een item. Alle items op Wikidata (dat zijn er op het moment van schrijven 95 miljoen) hebben een uniek nummer. Voor de koning is dat nummer Q154952 .
Prinses Beatrix, zijn moeder, heeft ook een nummer: Q29574. Beatrix en Willem-Alexander hebben een relatie: Beatrix is de moeder van Willem-Alexander. Je zegt daarom op Wikidata: item Q29574 (Beatrix) heeft als kind item Q154952 (Willem-Alexander).
Alle soorten relaties (dat zijn er meer dan 9.000) hebben óók een uniek nummer. Je kan bij zo’n relatie denken aan ‘is de hoofdstad van’, ‘is de schilder van’ of zoals bij Beatrix en Willem-Alexander: ‘heeft kind’. Het unieke nummer voor de relatie ‘heeft kind’ is op Wikidata P40. Nummers voor items (zoals de koning en zijn moeder) beginnen altijd met een ‘Q’. Nummers voor relaties (zoals ‘heeft kind’) beginnen met een ‘P’. Die ‘P’ staat trouwens voor property, want dat is hoe je een soort relatie noemt op Wikidata.
U vraagt zich wellicht af: waarom al dat gedoe met die nummers? Waarom heet Beatrix niet gewoon Beatrix? Helaas zijn namen alleen niet uniek genoeg. Er is bijvoorbeeld óók een item voor Beatrix (de voornaam, Q1096551), Beatrix (het cruiseschip, Q70114554) en Beatrix (een asteroïde, Q109927). En de persoon Beatrix zélf heeft meerdere namen. Vòòr haar abdicatie in 2013 hadden we het over ‘Koningin Beatrix’, nu over ‘Prinses Beatrix’. En in andere talen hebben ze ook weer een andere naam. In het Bulgaars hebben ze het bijvoorbeeld over ‘Беатрикс’. Namen veranderen en kunnen verschillen. Nummers veranderen nooit.
Terug naar de band tussen Beatrix en Willem-Alexander. De relatie ‘Beatrix heeft als kind Willem-Alexander’ zou je in SPARQL schrijven als:
wd:Q29574 wdt:P40 wd:Q154952
Je ziet dat er voor de items Q29574 (Beatrix) en Q154952 (Willem-Alexander) ‘wd:’ staat, en voor P40 (heeft kind) ‘wdt:’. Die letters noem je een prefix en geeft aan dat je alleen zoekt binnen Wikidata. Je kan met SPARQL namelijk ook door meerdere databases tegelijk zoeken. Dan moet wel duidelijk zijn over welke database je het hebt in je zoekvraag.
Stel dat je niet alleen Willem-Alexander zou willen vinden, maar alle kinderen van Beatrix. Dan zou je dit kunnen schrijven in SPARQL:
select ?child where { wd:Q29574 wdt:P40 ?child }
Hier staat dus zoiets als: “selecteer alle items die de relatie ‘kind van Beatrix’ hebben'”. Als je deze query (zo noem je zo’n zoekvraag) draait op de SPARQL query service van Wikidata krijg je een tabel met de nummers die horen bij Willem-Alexander, Constantijn en Friso.
Wat als je ook alle kleinkinderen van Beatrix wilt hebben? Dus de kinderen van de kinderen?
select ?child ?grandChild where {
wd:Q29574 wdt:P40 ?child.
?child wdt:P40 ?grandChild.
}
Oftewel: “selecteer alle kinderen van Beatrix, en geef me ook de kinderen van die kinderen”. Let op de punt aan het einde van elke regel om aan te geven dat je klaar bent met een triple.
Het resultaat is een lijst met 8 items: alle kleinkinderen van Beatrix mét hun vader. Voeg er nog wat extra dingen aan toe om ook de namen te krijgen (anders krijg je alleen de ID’s) en zet de netwerk-visualisatie-optie aan en je krijgt dit:
Misschien ontgaat je een beetje wat hier het praktisch nut van is. Want even googelen op ‘kleinkinderen beatrix’ levert hetzelfde op. Maar het aardige is dat je in die query alleen maar het nummer van ‘Beatrix’ hoeft te veranderen in dat van een willekeurig ander persoon met een item op Wikidata en je krijgt dáár de complete lijst van kinderen en kleinkinderen van. Of als je bijvoorbeeld álle voorouders van Willem-Alexander wilt hebben, en niet alleen z’n moeder. En het koningshuis is maar een voorbeeld. Wikidata heeft 95 miljoen items, dus of je het nou over schilderijen, monumenten of planten hebt: je kan ze gestructureerd doorzoeken.
Handig toch?