Fjerning av falske blanke noder - Utdanningsdirektoratet/Grep_SPARQL GitHub Wiki

Denne siden er en del av Videreutvikling

Vår referanse: GREPF-1711
Status: Satt i produksjon 06.12.2022

Beskrivelse

Denne saken handler om å fjerne jsonld-objekter i objekter med verdi = null. Dette fører til blanke noder i RDF som ikke leder til noe data - som med andre ord ikke gir noe verdi. Siden jsonld er kilden til den nattlige importen til GraphDB, vil dette påvirke vårt sparql-endepunkt direkte.

I denne oppgaven er fenomenet blanke noder i RDF nevnt, men også blanke noder for gyldighetsinformasjon. For mer informasjon om dette, se:




Vi kan ta utgangspunkt i et tilfeldig eksempel, KMS1023.jsonld: Denne fila finner du hvis du laster ned jsonld-dump (zip-fil), og åpner fila KMS1023 som ligger i denne zip-fila. Her ser vi at egenskapen "programfag" (som ligger på rot) har verdien null. I sparql vises derfor ikke "programfag", og det er slik det skal være.

Men – dette er ikke tilfelle for egenskaper som ikke ligger på rot, men som har underliggende objekter med egenskaper som alle har verdien null. I vårt eksempel:

"programfag": null, 
...
"gyldighet-etter-fag-AGR3Z01": {
   "gyldig-fra": null, 
   "gyldig-til": null
 }, 
 "gyldighet-tilhoerer-laereplan-AGR3-01": { 
   "gyldig-fra": null, 
   "gyldig-til": null 
  }
 }

Egenskapene "gyldighet-etter-fag-AGR3Z01" og og "gyldighet-tilhoerer-laereplan-AGR3-01", som begge ligger på rot, har hver seg underliggende egenskaper som har verdien null.

Hvis "gyldighet-etter-fag-AGR3Z01" = A, kan vi illustrere det slik:

A = { {∅}, {∅} }

Mengden A består altså av to objekter med tomme mengder/sett.

I praktisk SPARQL, ønsker vi strengt tatt ikke å betrakte tomme menger fordi da måtte regne på dem, dvs. vi må slå dem opp, konstatere at de er tomme, og vi må evt. gå tilbake og filtrere bort tomme mengder. Disse er i disse tilfellene likevel med, fordi de ligger under blanke noder, og først der vil de bli tatt i betraktning.

Med andre ord – både "gyldighet-etter-fag-AGR3Z01" og "gyldighet-tilhoerer-laereplan-AGR3-01" vises, selv om alle underliggende egenskaper har verdien null.

Egenskapen "programfag" ikke er med i sparql, fordi den representerer en tom mengde (har verdien null). SPARQL spiser ikke tomme mengder, noe vi vet fordi egenskapen "programfag" i KMS1023.jsonld ikke er med i sparql-treff. Men alle gyldighet-...-egenskapene med underliggende null-egenskaper blir med fordi de representerer objekter, og "herfra" kan vi ikke evaluere om de er tomme eller ikke før vi slår dem opp (objektene er i tillegg, siden vi snakker om objekt i objekt, blanke noder).

Problematikken, uttrykt med SPARQL:

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

Resultat, linjene 61 og 62:

p o
61 u:gyldighet-etter-fag-AGR3Z01 _:genid-144df53a2b53438481b043fef9612467-b062
62 u:gyldighet-tilhoerer-laereplan-AGR3-01 _:genid-144df53a2b53438481b043fef9612467-b1

og her er ikke u:programfag er ikke med i settet.

Siden u:gyldighet-etter-fag-AGR3Z01 og u:gyldighet-tilhoerer-laereplan-AGR3-01 gir blanke noder, spør vi slik for å se hva som ligger bak de blanke nodene:

PREFIX d: <http://psi.udir.no/kl06/>
select * where {
  d:KMS1023 ?p ?o .
  ?o ?p1 ?o1 .
  FILTER isBlank(?o)
} 

Filteret "isBlank" er med for å kun se på hva som ligger bak de blanke nodene, og ikke alt annet vi får under ?o. Resultatet er ingen treff.

Vi kan sjekke for å se på et annet eksempel (fagkode), og vi slår på "isBlank"-filteret allerede nå:

PREFIX d: <http://psi.udir.no/kl06/>
select * where {
  d:MAT1001 ?p ?o .
  FILTER isBlank(?o)} 

og får 12 treff der ?o er blanke noder.

Men spør vi videre på ?o, altså at vi nå krever at ?o skal inneholde noe,

PREFIX d: <http://psi.udir.no/kl06/>
select * where {
  d:MAT1001 ?p ?o .
  ?o ?p1 ?p1 .
  FILTER isBlank(?o)} 

får vi denne gangen bare 8 treff. Vi får altså i den første av de to siste spørringene fire falske treff.

Løsningsforslag

Ved forflatnings- og oppløftningsprosessen (det som skaper jsonld fra json som kilde) ønsker vi at i de tilfellene alle de underliggende egenskapene har verdien null, skrives dette f.eks slik:

"gyldighet-etter-fag-AGR3Z01": null

I de tilfellene der det finnes verdier, står objektet urørt, som f.eks. slik:

  "gyldighet-etter-fag-AGR3Z01": {
    "gyldig-fra": null,
    "gyldig-til": "2010-08-01T00:00:00"
  }
}

I det siste tilfellet, vil SPARQL kun vise gyldig-til og dennes verdi. Derfor er det viktig for oppgaveløsningen at vi ikke setter "gyldighet-etter-fag-AGR3Z01": til null hvis én av egenskapene i objektet har datoverdier.

Akseptansekrav:

AK.1

Gitt at jeg har lastet ned dump av jsonld fra https://data.udir.no/kl06/v201906/dump/jsonld (NB: bruk riktig url for miljøet du tester i), og åpner fila KMS1023.jsonld

Når jeg går til egenskapen "gyldighet-etter-fag-AGR3Z01"

skal jeg kunne se at den har verdien null, og ikke bestå av et objekt med egenskapene "gyldig-fra" og "gyldig-til" der begge har verdien null.

AK.2

Gitt at jeg går til SPARQL miljøet jeg skal teste i (enten https://sparql-beta-data.udir.no/sparql (Beta) eller https://sparql-data.udir.no/sparql (Prod) (her har vi utelatt de interne testmiljøene)

Når jeg kjører følgende spørring og iterativt erstatter "u:laereplan" med "u:xxx" i de kommenterte linjene så jeg til sammen kjører 7 spørringer:

PREFIX u: <http://psi.udir.no/ontologi/kl06/>
select * where {
# u:laereplan
# u:laereplan_lk20
# u:kompetansemaalsett
# u:kompetansemaalsett_lk20
# u:fagkode
# u:opplaeringsfag
# u:programfag
# u:merknad
# u:programomraade
 ?s a u:laereplan ;
 ?p1 ?o1 .
 FILTER NOT EXISTS {?o1 ?p2 ?o2 .}
 FILTER REGEX(str(?p1), "gyldighet", "i")
} ORDER BY ?p1

skal jeg få ingen treff.

Før vi har gjort denne oppgaven, gir

  • u:laereplan 315 treff
  • u:laereplan_lk20 24 treff
  • u:kompetansemaalsett 1774 treff
  • u:kompetansemaalsett_lk20 1 treff
  • u:fagkode 40 893 treff
  • u:opplaeringsfag 4833 treff
  • u:programfag 123 treff
  • u:merknad 10 treff
  • u:programomraade 1489 treff

Med andre ord, i skrivende stund får vi rensket bort til sammen 49 462 falske blanke noder etter at denne oppgaven er gjort (se spørring pr. type eller spørring totalt).

AK.3

Gitt at jeg går til SPARQL miljøet jeg skal teste i (som definert i A.K.2)

Når jeg kjører følgende spørring og iterativt erstatter "u:laereplan" med "u:xxx" i de kommenterte linjene så jeg til sammen kjører 7 spørringer (obs - ikke samme liste som i AK.2):

PREFIX u: <http://psi.udir.no/ontologi/kl06/>
PREFIX d: <http://psi.udir.no/kl06/>
select * where {
# u:laereplan
# u:kompetansemaalsett
# u:kompetansemaalsett_lk20
# u:fagkode
# u:opplaeringsfag
# u:programomraade
# u:utdanningsprogram
 ?s a u:laereplan ;
 ?p1 ?o1 .
 ?o1 ?p2 ?p3
 FILTER REGEX(str(?p1), "gyldighet", "i")
} ORDER BY ?p1

skal jeg få verdiene, u:gyldig-fra, og/eller u:gyldig-til i p2-kolonnen, og datoverdier i p3-kolonnen (bare en ekstra sjekk så vi ikke mister blanke noder med innhold, som det pr. 29.06.2022 er 43 970 av).

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