SPARQL‐kurs ‐ del 4 - Utdanningsdirektoratet/Grep_SPARQL GitHub Wiki

Denne siden er en del av SPARQL-kurs

<-- del 3   del 5 -->

Del 4, Flere baller i lufta


I de tidligere delene har vi blant annet sett på hvordan vi med en sparql-spørring kan liste opp alle typene/klassene i Grep, og vi har valgt oss én type, og vi har slått opp én forekomst og deretter "brettet" dette elementet ut for å se hva den inneholder.

I denne delen skal vi ha flere baller i lufta samtidig. Vi skal blant annet kunne slå opp et element, og vi skal via dette elementet slå opp tilhørende eller relaterte elementer og se hva disse har å tilby av data. Vi skal "traversere" og "parse".

Parse:
Tenk deg at du har en oppskrift på en kake. Parsing er som å lese denne oppskriften og forstå hva som står der. Det innebærer å identifisere ingrediensene, mengdene, og instruksjonene i oppskriften slik at du vet hva du trenger og hva du skal gjøre for å lage kaken. Med andre ord, parsing handler om å tolke og strukturere informasjon fra en tekst eller data.

Traversere:
Forestill deg at du har laget kaken og den står foran deg med flere lag. Traversering er som å undersøke kaken lag for lag. Du ser på toppen, deretter skjærer du gjennom hvert lag og ser hva som er inni. I data-verdenen betyr det å gå gjennom en strukturert datastruktur (som et tre eller en liste) og besøke hver enkelt del av den. Det handler om å navigere gjennom dataene som er blitt strukturert.

Parsing er å forstå og strukturere dataene, mens traversering er å navigere gjennom og undersøke de strukturerte dataene.

[Her har jeg bedt ChatGPT forklare disse begrepene. Ikke den dummeste forklaringen jeg har sett...]

Vi har sett at et element (en forekomst av en type/grep-type) han inneholde flere typer ting, eller sagt på en annen måte; et element kan ha flere typer ting på objekt-plassen når du ser på elementet. Det kan være tekststrenger og tall, men det kan også være referanser til andre elementer. Det er det vi skal beskjeftige oss med videre i denne delen.

Litt om sjargongen her. Når vi har slått opp et element, så har vi en triple i spørringen som starter med [referansen til elementet] [predikat] [objekt]. Da sier vi ofte at vi "står på" dette objektet. Vi "står på d:NOR01-06" og spør videre på... noe annet". Vi traverserer.

En av de andre type tingene du ser på objekt-plassen for et element, er som vi har nevnt, referanser til andre elementer, f eks. at en fagkode kan være koblet til ett eller flere opplæringsfag, eller at en læreplan har ett eller flere kompetansemålsett. Det siste (det at læreplanen har flere kompetansemålsett) kan se slik ut hvis spørringen din er d:NOR01-06 ?p ?o der "NOR01-06" er læreplankoden:
image
Denne læreplanen har koblinger til 9 kompetansemålsett, men hva disse heter og hva de inneholder er ukjent for oss her vi står nå. Vi må traversere og parse videre for å få tak i den informasjonen. Det eneste vi har (og som vi ser her vi står nå), er identifikatoren (URIen) som tar oss til den informasjonen. Det blir som å ringe noen for å kommunisere videre om hva den i andre enden har å melde.

Med den kunnskapen vi har til nå, så kan vi jo ta en stikkprøve, og slå opp ett av disse kompetansemålsettene som læreplanen er relatert til. La oss slå opp d:KV116 (der "KV116" er koden til et kompetansemålsett):

"KV" i "KV116" står for "kompetansemål og vurdering" etter kapittelet i læreplanen

PREFIX d: <http://psi.udir.no/kl06/>
select * where { 
    d:KV116 ?p ?o
}

image
Men alt dette kunne vi ikke se fra d:NOR01-06 selv om vi faktisk sier at kompetansemålsettene er en del av denne læreplanen. Vi sier også at læreplanen består av disse og disse kompetansemålsettene.

Termen "Kompetansemålsett" er noe vi i Grep-teamet har funnet opp og konstruert for å kunne digitalisere læreplanen. Den jobben krevde bl.a. at vi delte opp læreplanen og dens bestanddeler i mindre deler (som vi gjordet til egne typer elementer), og én av dem er kompetansemålsett. Den er da ment til blant annet å fungere som en "kontainer" for kompetansemålene for de ulike målgruppene eller fagene i læreplanen (den inneholder også en del tekst-elementer som handler om vurdering). Definisjonen på et kompetansemålsett (LK20) i Grep er: "Et sett med kompetansemål, som gjelder for et angitt trinn eller nivå etter Kunnskapsløftet LK20 (fagfornyelsen)"

Vi traverserer

OK – til nå har vi, hver for seg, slått opp "NOR01-06" og "KV116". Men det er nå moroa begynner; vi skal i en spørring stå på "NOR01-06" og traversere oss videre ned i strukturen etter lista over kompetansemålsett for denne læreplanen. Så skal vi hente fram (parse) tittelen til de ulike kompetansemålsettene:

PREFIX d: <http://psi.udir.no/kl06/>
PREFIX u: <http://psi.udir.no/ontologi/kl06/>
select * where { 
    d:NOR01-06 u:kompetansemaalsett ?kms . # vi får opp "nummeret" til "kms"
    ?kms u:tittel ?kmsTittel .             # Vi ringer "kms" og ber om tittel
    FILTER(LANG(?kmsTittel)="default")
}

Da får vi dette resultatet:
image
...og ikke tenk på rekkefølge ennå

Det vi altså har gjort, er at vi i den første linja i SELECT-delen, slår opp en gitt læreplan. Variabelen på objekt-plassen har vi for enkelhets skyld bare kalt "?kms" (for kompetansemålsett), for det er jo en liste av kompetansemålsett ligger bak dette objektet siden vi i predikatet ber om u:kompetansemaalsett. Så er det punktum, og ny linje. Vi henter fram igjen det som vi satt på objekt-plassen i forrige linje, og setter dette inn som subjekt i neste linje, og spør videre derfra: ?kms u:tittel ?kmsTittel. Da vi kun slo opp "KV116" ovenfor, la du merke til egenskapen "rekkefoelge" i resultatet? Se evt. også bildet under spørringen ovenfor (rad 17). Nå kan vi faktisk benytte oss av den for å sortere kompetansemålsettene i det endelige resultatsettet:

PREFIX d: <http://psi.udir.no/kl06/>
PREFIX u: <http://psi.udir.no/ontologi/kl06/>
select * where { 
    d:NOR01-06 u:kompetansemaalsett ?kms .
    ?kms u:tittel ?kmsTittel ;
         u:rekkefoelge ?kmsR.    # Her henter vi fram rekkefølge
    FILTER(LANG(?kmsTittel)="default")
}
# Og i linjen nedenfor bruker vi rekkefølgen til å sortere resultatet
ORDER BY ?kmsR  

image
Vi henter fram rekkefølgen ved hjelp av ?kms u:rekkefoelge ?kmsR, så bruker vi det i siste linje i spørringen etter ORDER BY.

Øvelse 1: Traversere og parse kompetansemål fra kompetansemålsett

Kan du overføre det vi har sett på til nå, til også å liste opp kompetansemålene til hvert enkelt kompetansemålsett, og i tillegg sortere kompetansemålene? Med andre ord – kan du liste alle kompetansemålene til hvert kompetansemålsett for NOR01-06, og samtidig ta med kompetansemålenes tittel på default-språket?

Se "fasit" nederst på siden.



Oppsummering, del 4

I denne delen har vi sett på hvordan du kan

  • traversere og
  • parse

nedover i en SPARQL-struktur.

Og sammen med de første delene, kan du liste opp hvilke typer som er tilgjengelig, og du kan utforske disse og lage spørringer for å grave videre i strukturen. Kanskje det er en litt djerv påstand, men jeg tror at hvis du behersker det vi har vært igjennom til nå, har du inne brorparten av det du trenger for å finne ut av ting ved hjelp av SPARQL. Men for å beherske det, krever det en del øving, prøving og feiling, og det skjer ikke av seg selv.

Gå til "SPARQL-eksempler" og siden "Noen sparql-tips og triks". Her kan du studere og kjøre noen av spørringene og se om du nå henger med. Det er riktig nok en del elementer på disse sidene vi ikke har vært igjennom, men plukk ut ting som virker kjent til nå, og studer og prøv ut.





<-- del 3   del 5 -->




Fasit, øvelser

Fasit, Øvelse 1: Traversere og parse kompetansemål fra kompetansemålsett

Svaret er egentlig bare å gjøre nøyaktig det samme for kompetansemål som vi gjorde for kompetansemålsett. Du har kanskje kalt variablene noe annet enn meg, men her er et forslag:

PREFIX d: <http://psi.udir.no/kl06/>
PREFIX u: <http://psi.udir.no/ontologi/kl06/>
select * where { 
    d:NOR01-06 u:kompetansemaalsett ?kms .
    ?kms u:tittel ?kmsTittel ;
         u:rekkefoelge ?kmsR ;
         u:kompetansemaal ?km .
    ?km u:tittel ?kmTittel ;
        u:rekkefoelge ?kmR .
    FILTER(
        (LANG(?kmsTittel)="default") &&
        (LANG(?kmTittel)="default")
    )
}
ORDER BY ?kmsR ?kmR

Hvis du ønsker, kan du jo droppe å vise ?kms ?kmsR ?km og ?kmR. Da skriver du bare de variablene du vil ha med i stedet for * etter SELECT, f.eks.:

PREFIX d: <http://psi.udir.no/kl06/>
PREFIX u: <http://psi.udir.no/ontologi/kl06/>
select ?kmsTittel ?kmTittel where { 
    d:NOR01-06 u:kompetansemaalsett ?kms .
    ?kms u:tittel ?kmsTittel ;
         u:rekkefoelge ?kmsR ;
         u:kompetansemaal ?km .
    ?km u:tittel ?kmTittel ;
        u:rekkefoelge ?kmR .
    FILTER(
        (LANG(?kmsTittel)="default") &&
        (LANG(?kmTittel)="default")
    )
}
ORDER BY ?kmsR ?kmR





<-- del 3   del 5 -->



⚠️ **GitHub.com Fallback** ⚠️