Introductie in het schrijven van SPARQL queries met interactieve voorbeelden.


In deze tutorial maken we de gebruiker bekend met het schrijven van queries in de querytaal SPARQL. Deze taal is speciaal gemaakt om Linked Data sets te bevragen. We schrijven deze tutorial in de vorm van en data story, waardoor je na een stukje uitleg een query kunt bekijken, veranderen en opnieuw uitvoeren. In deze data story zie je de queries, maar bij andere stories zijn ze nog wel eens verborgen. Je kunt de query alsnog laten verschijnen als je klinkt op dit symbool: . Als je de query openklapt zie je linksbovenaan het endpoint. Dit is de plek waar de query naar toe wordt gezonden. We maken voor deze tutorial gebruik van data met bibliografische informatie van de Koningklijke Bibliotheek (KB), dit wordt gepubliceerd op haar Linked Data omgeving. We proberen er achter te komen hoeveel boeken over dieren in de jaren zestig door vrouwelijke auteurs geschreven zijn.

De basis: hoe wordt een SPARQL query opgebouwd?

Linked data sets zijn vrijwel altijd opgeslagen als triples: alle data punten hebben het format subject predicaat object. Het subject en object zijn vaak dataobjecten die waarvan de relatie wordt gedefinieerd door het predicate. Een voorbeeld zou zijn Max Havelaar isVanType Boek, of Max Havelaar isGeschrevenDoor Multatuli. In linked data sets zijn de de eerste twee elementen van de triple altijd IRIs: ze verwijzen naar hun formele definitie. Het derde element kan ook een IRI zijn, ofwel een Literal, een waarde. De predicaten kunnen bijvoorbeeld zijn gedefinieerd door een internationale organisatie, bijvoorbeeld W3C, terwijl de definitie van Max Havelaar door de KB wordt bijgehouden. We richten ons in deze tutorial op de select query, zodat iedereen eigen data stories kan gaan maken of bevragingen kunnen gaan inzetten in eigen apps. Er zitten drie elementen in een select query: Projectie , Patroon en Modifier . De projectie geeft aan welke variabelen er moeten worden teruggegeven. Het patroon is voor deze tutorial het belangrijkste: hier specificeren we welke data uit de dataset we terug willen. Tenslotte is er de modifier, dit is de plek waar we nog extra berekeningen kunnen doen over onze opgevraagde data.

Laten we beginnen door het subject predicaat object patroon af te vuren op het endpoint, waarbij we alle drie als variabele meegeven. We leggen dus nog geen patroon beperkingen op.

De voorgaande query was nog niet een heel nuttige query, we krijgen simpelweg vijf datapunten terug uit de dataset. We zien al wel dat we op alles kunnen klikken aangezien het allemaal IRIs zijn. De elementen in de subject posities verwijzen naar de data van de KB, als je hier op klikt zie je alle informatie over dat specifieke item in de browser

Als we nu graag willen welke unieke relaties, predicaten voorkomen in de data, dan kunnen we een distinct keyword meegeven. Laten we gelijk wat meer over de projectie leren. In de projectie kunnen we variabele namen binden aan andere namen. Dit is bijvoorbeeld handig als je de query leesbaar wilt maken voor iemand die de dataset goed kent, maar het resultaat leesbaar wilt maken voor iemand die alleen de selectie te zien krijgt. Tenslotte doen we ook al een intuïtieve berekening in het projectie stukje: we tellen hoe veel ?subjects het unieke predicaat hebben, en dit noemen we het aantal.

We hebben net gezien dat alle IRIs een beetje onoverzichtelijk kunnen worden. Zeker als we al kennis hebben over een data set en restricties op het patroon gaan opleggen willen we niet steeds een hele IRI hoeven opschrijven. Daarom wordt er vaak aan het begin van een SPARQL query een aantal prefixes. Deze zijn letterlijk een stuk hyperlink die op de plek dat we deze later in de query gebruiken wordt toegevoegd om een complete IRI te vormen. We zagen in bij de vorige query dat het rdf:type (volledig http://www.w3.org/1999/02/22-rdf-syntax-ns#type) de meest gebruikte relatie. We definieren een prefix in de volgende query en kijken welke typen er voorkomen in de data.

We zagen in de vorige query bij resultaat 9. dat http://schema.org/Book een type is dat voorkomt in de data, uiteraard is dat niet heel onverwacht voor een dataset van de KB! We kunen nu een paar boek objecten weergeven. We gebruiken rdf:type zo vaak dat we deze zelfs de shorthand a hebben gegeven. Dit gebruiken we hier.

Een kleine Disclaimer: we hebben nu de data een beetje verkend met SPARQL, maar dit is wellicht eenvoudiger met een visuele interface, door bijvoorbeeld door de data te browsen of pagina's van het data model te bekijken. Hopelijk is het nu wel duidelijk gemaakt hoe we een simpel patroon matchen. We gaan nu verder met het matchen van complexere patronen. Omdat veel hiervan in de query gebeurt staat daar vanaf nu het meeste commentaar.

Het matchen van graafpatronen

We zagen zojuist vijf boekobjecten, maar dat is natuurlijk nog niet een heel mooie weergave, laten we wat extra informatie informatie ophalen. We maken nu een uitgebreider patroon om te matchen.

Stel je wilt zoeken op een specifiek onderwerp, bijvoorbeeld dieren.
Laten we eens kijken of dit onderwerp voorkomt in de beschikbare thesauri in de LOD omgeving.

Inspectie van het resultaat door de links te volgen brengt ons tot de conclusie dat dieren uit de Brinkman het handigste trefwoord is.

Even een extra controle, welke onderwerp hebben deze Brinkman term als bovenliggende term (ergens in de hierarchie)

De lijst is beperkt tot de eerste 10, verwijder limit 10 in de query om alle resultaten te zien. Het resultaat ziet er goed uit!

Dus nu boeken zoeken die over dieren gaan. We maken hierbij gebruik van een union die een stuk graaf teruggeeft dat aan een van twee voorwaarden moet voldoen.

Opmerking: In deze lijst zien we titels beginnend met '#10#'' of '#20#'. Dit is het gevolg van een incorrecte conversie vanuit de bron naar Linked Data.

Nu selecteren we op boeken die in de jaren 60 gepubliceerd zijn gepubliceerd, dit levert de volgende boeken op:

Maar misschien willen we liever weten hoeveel boeken er in de jaren 60 zijn gepubliceerd, dit doen we met bijna dezelfde query maar door alleen de projectie aan te passen (hier zit wel een impliciete agregatie in).

Queries over meer dan één database

De KB heeft heel mooi alles bijgehouden over boeken en auteurs, maar we kunnen er helaas geen afbeeldingen vinden van auteurs. Gelukkig kunnen we dankzij de kracht van Linked (Open) Data er wel afbeeldingen bij zoeken! We maken hiervoor een federated query: een query die van meerdere endpoints gebruik maakt. We gebruiken hiervoor de clause service. We weten bijvoorbeeld dat de nta_uri is opgenomen in de wikidata catlogus. Verder kunnen we door wat zoeken in dbpedia terugvinden dat deze de wikidata identifiers kan koppelen aan eigen identifiers via owl:sameAs en aan deze eigen identifiers hebben ze wikipedia plaatjes gekoppeld. Het lijkt een omweg, maar met een paar regels code bevragen we meerdere datasets in de wereld om zo onze gewenste informatie bij elkaar te krijgen. Stel je eens voor dat alle data zo werkte.

Het geslacht van een auteur is helaas niet opgenomen in de NTA. Dit is wel in Wikidata te vinden. Zoals we zagen bij de vorige query heeft Wikidata ook een relatie met de nta_uri, dus daarmee kunnen we een match maken. Vanwege de performance hebben we er hier voor gekozen om een aparte dump te maken en deze voorlopig in demo omgeving van NDE te zetten (merk op dat dit geen federated query is maar we wel een ander endpoint bevragen als startpunt - we zoeken wel alleen in een bepaalde graph). Op basis van de Wikidata gegevens wordt er aan alle NTA ingangen (die in Wikidata bekend zijn) een extra veld voor geslacht op genomen. Het resultaat ziet er als volgt uit.

De waarde voor schema:gender zijn nog de oorspronkelijke waarden die Wikidata gebruikt om een geslacht te typeren: zo is Q6581097 mannelijk en Q6581072 vrouwelijk.

Als we dit alles combineren krijgen we het antwoord op de vraag die we ons aan het begin van deze tutorial stelde, namelijk welke boeken in de jaren 60 door vrouwen zijn geschreven.

Als disclaimer noemen we dat deze berekening de volgende onnauwkeurigheden bevat:
- niet alles wat gepubliceerd is staat beschreven in de NBT Linked Data set
- boeken met niet gethesaureerde auteurs zijn niet mee geteld (in deze set: minder dan 1 procent)
- boeken van auteurs die niet in Wikidata voorkomen zijn ook niet mee geteld (bijna 60 procent)
- boeken zonder Brinkman trefwoord zijn niet meegeteld
- boeken zonder publicatiedatum zijn niet meegteld
=> dus 2 is waarschijnlijk te laag, 5 komt dichter in de buurt....

Na het volgen van en rondspelen met deze tutorial hopen we dat jullie je bekend hebben gemaakt met SPARQL en jullie kunnen beginnen om zelf SPARQL queries te schrijven. Er staan op de website van de HACKALOD nog vele uitgebreide data stories om verder inspiratie op te doen. Heel veel succes en plezier iedereen!