Ontologi for Grep - Utdanningsdirektoratet/Grep_SPARQL GitHub Wiki
Les gjerne "Hvordan bruke Greps SPARQL-tjeneste#workbench-for-mennesker" for å gå i dybden på hvordan du bruker SPARQL.
Vi har laget et utkast til ontologi for Grep og lagt denne i et eget SPARQL-repo i Beta. Gå til https://sparql-beta-data.udir.no/sparql og velg repositoriet "Ontologi".
Du kan også se ontologien som fil, og da i Turtle-serialisering: owl-eksperiment_kl06_20230324.ttl.
- Klasser
- alle grep-typer er definert som owl:Class (i tillegg til rdf:type)
- Objekt-egenskaper (owl:ObjectProperty)
- egenskaper som refererer til ett eller flere andre objekter der "range" er en URI i Grep
- Data-egenskaper (owl:DatatypeProperty)
- egenskaper som har "range" en gitt datatype (f.eks
rdfs:range rdf:langString
(språkversjonert literal)
- egenskaper som har "range" en gitt datatype (f.eks
Alle klassene og egenskapene (både objekt- og datatypeegenskaper) er beskrevet med prosa via hvert objets rdfs:label og rdfs:comment. F.eks. slik:
@prefix : <http://psi.udir.no/ontologi/kl06/> .
@prefix d: <http://psi.udir.no/kl06/> .
@prefix u: <http://psi.udir.no/ontologi/kl06/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix udir: <http://psi.udir.no/ontologi/> .
@base <http://psi.udir.no/ontologi/kl06/> .
u:laereplan_lk20 rdf:type owl:Class ;
rdfs:subClassOf udir:Laereplan ;
rdfs:comment "Element som uttrykker den samlede kompetansen en elev, lærling, lærekandidat eller deltaker skal ha etter endt opplæring på et gitt nivå/trinn i ett eller flere fag etter Kunnskapsløftet LK20, fagfornyelsen"@nb ,
"Element that indicates the overall competence a student, apprentice, training candidate or participant must have after completing training at a specified level/year-level in one or more subjects according to the Knowledge promotion (LK20)"@en ;
rdfs:label "Curriculum (LK20)"@en ,
"Læreplan (LK20)"@nb .
På den måten fungerer ontologien som et oppslagsverk for hva som menes med de ulike objektene.
Legg spesielt merke til at både u:laereplan_lk20 og u:laereplan er underklasser av Laereplan (med stor L) som ligger i et annet navnerom enn ellers i Grep, nemlig http://psi.udir.no/ontologi/ og ikke som ellers, http://psi.udir.no/ontologi/kl06/. Se u:laereplan_lk20 rdfs:subClassOf udir:Laereplan
i koden over, og se også prefiksen "udir:" øverst i dokumentet. På den måten (og det er en del av eksperimentet vårt) har vi beriket modellen med hierarki der dette er naturlig. Vi har gjort det samme med
- udir:Kompetansemaal
- u:kompetansemaal
- u:kompetansemaal_lk20
- udir:Kompetansemaalsett
- u:kompetansemaalsett
- u:kompetansemaalsett_lk20
Hadde vi bakt inn denne ontologien i hoved-repoet (201906), kunne vi spurt etter forekomster av udir:Laereplan og fått en liste med alle læreplaner (både lk06- og lk20-planer). Men siden dette foreløpig bare er et eksperiment, har vi ikke blandet ontologien med dataene. I sandkasse-miljøet har vi gjort det. Se http://sandkasse-data.udir.no:7200/sparql og repoet "Grep_owl-eksperiment". Der kan du spørre direkte:
PREFIX udir: <http://psi.udir.no/ontologi/>
select * where {
?lp a udir:Laereplan .
} ORDER BY ?lp
og du får 998 læreplaner i retur (altså begge læreplantypene).
Men tilbake til Beta og repoet "Ontologi":
Siden ontologi og data er adskilt kan vi likevel få samme resultat, men vi må gjøre noen triks:
Stå i repoet Ontologi, og kjør følgende spørring:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?lp where {
?laereplan rdfs:subClassOf <http://psi.udir.no/ontologi/Laereplan>
SERVICE <repository:201906> {
?lp a ?laereplan
}
} order by ?lp
og du får de samme 998 læreplanene som i forrige spørring.
Trikset er bare at vi gjøre et såkalt federert søk mot et annet repo enn det vi står i (SERVICE <repository:201906>
). Merk at det ikke er likegyldig hvor du står og hvilken vei du "federerer". Spørringen over, bare snudd, er en mye tyngre spørring:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?lp where {
?lp a ?laereplan
SERVICE <repository:Ontologi> {
?laereplan rdfs:subClassOf <http://psi.udir.no/ontologi/Laereplan>
}
} order by ?laereplan
Denne spørringen tok 34s. da vi sjekket sist, mens den forrige tok bare 0.1s. Årsaken er at vi i denne spørringen i prinsippet har en s-p-o-spørring (?s ?p ?o
), altså at vi tar utgangspunkt i tre variabler, som i praksis betyr alle tripler i hele databasen. Spørringen løper da igjennom alle tripler, og sjekker mot det vi har skrevet under repository:Ontologi
for hver trippel. Det er tungt.
# Query that returns all classes in Grep with labels and definitions
# Go to https://sparql-beta-data.udir.no/sparql
# Select the "Ontologi" repo at the top right of the page
# Paste the query below into the query window and click "Run
PREFIX u: <http://psi.udir.no/ontologi/kl06/>
PREFIX udir: <http://psi.udir.no/ontologi/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://psi.udir.no/ontologi/kl06/>
select * where {
?type rdf:type owl:Class ;
rdfs:label ?labelEN ;
rdfs:label ?labelNB ;
rdfs:comment ?commentEN ;
rdfs:comment ?commentNB .
OPTIONAL {?type rdf:type owl:Class ; rdfs:subClassOf ?subClassOf}
FILTER (lang(?commentEN)="en" && (lang(?commentNB)="nb" && (lang(?labelEN)="en" && (lang(?labelNB)="nb"))))
} ORDER BY ?type
Siden "Liste over alle properties/egenskaper" i REST-wikien vår er bygget på ontologien som er beskrevet over. Den samme oversikten er mulig å nå via spørringen nedenfor. Gå til https://sparql-beta-data.udir.no/sparql og velg repoet "Ontologi" oppe i høyre hjørne, klikk deretter på "SPARQL" i venstremenyen og kjør følgende spørring:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT
?property ?tittel ?definisjon ?label ?definition
(concat(group_concat(distinct ?dom;separator=', ')) as ?domain)
(concat(group_concat(distinct ?rng;separator=', ')) as ?range)
WHERE {
?property a owl:DatatypeProperty ; # evt owl:ObjectProperty
rdfs:label ?label ;
rdfs:label ?tittel ;
rdfs:comment ?definisjon ;
rdfs:comment ?definition ;
rdfs:domain ?dm ;
rdfs:range ?rg .
FILTER(lang(?tittel)="nb")
FILTER(lang(?definisjon)="nb")
FILTER(lang(?label)="en")
FILTER(lang(?definition)="en")
BIND(REPLACE(STR(?dm), ".*/", "") AS ?dom)
# enten
#BIND(REPLACE(STR(?rg), ".*/", "") AS ?rng)
# eller:
BIND(REPLACE(STR(?rg), ".*[/#]", "") AS ?rng)
}
GROUP BY ?property ?tittel ?definisjon ?label ?definition
ORDER BY ?property
Endre fra owl:DatatypeProperty til owl:ObjectProperty i den første linjen etter WHERE-klausulen for å bytte til å vise alle owl:ObjectProperty
Ta kontakt med oss om du har synspunkter om dette, har ideer eller forslag til endringer.