Sunteți pe pagina 1din 12

Exerciii cu interogri SPARQL n Sesame

Instrumente necesare:

Conexiune internet
Tomcat (necesit ca Java s fie instalat corect)
Sesame (necesit ca Java s fie instalat corect)

Obiectiv principal: nvarea modului de creare i editare a bazelor de cunotine Sesame

Descrcai Sesame de la adresa de mai jos (exemplele au fost testate pe Sesame 2.x. Ar trebui s
funcioneze i pe Sesame 4.x lansat n cursul acestui an, dar pentru a evita surprizele, recomandm s
lucrai cu Sesame 2.8)
http://rdf4j.org/download.docbook?view

Sesame este disponibil n mai multe forme, n funcie de modul n care urmeaz a fi folosit:

Ca i aplicaie n linia de comand (directorul bin);


Ca i bibliotec Java (directorul lib);
Ca i aplicaie web de rulat pe serverul Tomcat (directorul war, fiierul openrdf-workbench);
Ca i serviciu de tip REST, de rulat pe serverul Tomcat (directorul war, fiierul openrdf-sesame).

Creai o baz de cunotine de tip "in-memory" n Sesame

Salvai textul de mai jos n fiierul sample.ttl din directorul C:\rdf.


@prefix : <http://expl.at#>.
:Anna :hasHairColor :Red; :hasAge 20; :daughterOf :John.
:Mary :daughterOf :John.

Pornii consola Sesame (din pachetul Sesame pe care l-ai downloadat) bin/console.bat (necesit Java) 1.
Putei obine lista cu comenzi disponibile dac tiprii help n linia de comand:
>help.

Realizai validarea fiierului sample.ttl


>verify c:\rdf\sample.ttl.

Conectai-v la directorul pe care l-ai creat i care va constitui directorul de lucru pentru bazele de
cunotine create cu linia de comand:
>connect c:\rdf.

Creai o baz de cunotine de tip "in-memory":


>create memory.

1
Asigurai-v c Java s-a instalat corect. Dac fereastra consolei se nchide imediat dup ce pornete nseamn c
nu s-a setat variabila de mediu JRE_HOME (dac avei Java JRE) sau JAVA_HOME (dac avei Java JDK).
Va trebui s completai urmtoarele:

Repository ID = myrepo
Repository title = myrepo
Persist = true (dac dorim s se salveze datele pe hard-disk cnd se nchide consola)
Sync delay = 0 (dac dorim s scrie pe hard disk de fiecare dat cnd se fac modificri)

Deschidei depozitul de cunotine creat:


>open myrepo.

Prompter-ul va indica (similar cu MySQL!) faptul c lucrai n myrepo. ncrcai fiierul sample.ttl n
depozitul creat.
myrepo> load c:\rdf\sample.ttl.

Interogai ntregul coninut al depozitului creat:


myrepo> sparql select * where {?x ?y ?z}.

Modificai configuraiile astfel nct s afieze URI-urile complete:


myrepo> set showprefix=false.

Repetai interogarea, ns de aceast dat va arta afirmaiile cu URI-uri complete:


myrepo> sparql select * where {?x ?y ?z}.

Introducei o nou afirmaie n baza de cunotine:


myrepo> sparql insert data {<http://expl.at#Andrew> <http://expl.at#isBrotherOf> <http://expl.at#Peter>}.

Extragei toate afirmaiile i observai-o pe cea nou:


myrepo> sparql select * where {?x ?y ?z}.

tergei toate afirmaiile despre Anna:


myrepo> sparql delete where {<http://expl.at#Anna> ?p ?o}.

Repetai interogarea de coninut al bazei de cunotine i va arta doar dou afirmaii:


myrepo> sparql select * where {?x ?y ?z}.

tergei toate afirmaiile:


myrepo> sparql drop all.

nchidei baza de cunotine:


myrepo> close.

tergei baza de cunotine:


drop myrepo.
Creai o baz de cunotine Sesame prin interfaa Web Workbench

Descrcai Tomcat la adresa http://tomcat.apache.org/download-80.cgi (exerciiile au fost testate n


Tomcat 8). Descrcai varianta ZIP, nu service installer, pentru a evita conflictele cu alte servere
existente pe calculator!

Copiai coninutul directorului War din pachetul Sesame (2 fiiere) n directorul webapps din Tomcat.
Pornii serviciul Tomcat din Tomcat\bin\startup.bat. Pornii browser-ul (preferabil Firefox) i lansai
aplicaia Web Sesame la adresa: http://localhost:8080/openrdf-workbench. n panoul din stnga a
interfeei Sesame selectai Repositories-New repository cu urmtorii parametri:

Type = Native Java Store


ID = MyRepo
Title = MyRepo
Triple indexes = spoc, posc

Salvai urmtoarele date n fiierul movies.trig.


@prefix : <http://expl.at#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>. Toate datele sunt grupate n acest graf identificat
:mymoviegraph
{:JamesCameron :directorOf :Avatar,:Terminator; Afirmaii multiple despre acelai subiect i aceeai
:hasName "James Cameron".
proprietate
:JohnMcT :directorOf :Predator, :DieHard;
:hasName "John McTiernan"; Noduri anonime ca structuri de date
:birthInfo _:birthdetails.
_:birthdetails :date "1951-01-08"^^xsd:date;
:place :SUA.
:McG :directorOf _:somemovie; Noduri anonime folosite pentru a ine locul unei
:hasName "Joseph McGinty"; resurse neidentificate
:hasNickname "McG".
:SamWorth :hasName "Sam Worthington";
:playedIn :Rogue, _:somemovie;
:playedTheRole [:character :JakeSully; Nod anonim pentru a exprima relaii cu aritate 3
:movie :Avatar].
:Arnold :playedIn :Terminator,:Predator;
:wasGovernorOf :California;
:hasName "Arnold Schwarzenegger";
:birthInfo [:date "1947-07-10"^^xsd:date;
:place :Austria].
:LindaH :hasName "Linda Hamilton";
:playedTheRole [:character :SarahConnor;
:movie :Terminator].
:ShBlack :playedIn :Predator;
:hasName "Shane Black".
:Terminator :hasTitle "Terminator";
:hasBudget 6400000 .
:Rogue :hasTitle "Rogue".
Se va lsa un spaiu ntre valorile ntregi i punct
:Avatar :hasTitle "Avatar";
pentru a se evita confuzia cu punctul zecimal
:hasBudget 237000000 .
:DieHard :hasTitle "Die Hard".
:Predator :hasTitle "Predator";
:hasBudget 18000000 .
:JakeSully :hasName "Jake Sully". Etichete /nume scrise n mai multe limbi
:SarahConnor :hasName "Sarah Connor".
:California :hasName "California"@en, "Californie"@fr.
:Austria :hasName "Austria"@en, "Autriche"@fr.
:SUA :hasName "United States of America"@en, "Etats Unis d'Amerique"@fr.}
Observai c fiierul e scris n sintaxa TriG (are cunotinele grupate ntre acolade, ntr-un "graf
identificat"). n Sesame, grafurile identificate se mai numesc i contexte.

ncrcai fiierul n Sesame, folosindu-v de Modify/Add i urmtoarele opiuni:

RDF Data File = cutai fiierul movies.trig

Data format = TriG

Cmpul Context ar trebui s rmn liber deoarece contextul (:mymoviegraph) este luat direct
din fiier; dac se ncarc un fiier fr graf identificat, atunci contextul poate fi introdus
manual);

Apsai Upload.

Putei converti datele n sintaxa dorit cu opiunea Export (n cazul n care selectai un format care nu
suport grafuri identificate precum N-Triples, Turtle, identificatorul contextului nu va fi exportat). n
fereastra Export, putei da clic pe oricare din URI-uri pentru a extrage toate afirmaiile despre acel URI.
Observai cum arat nodurile anonime nu mai sunt la fel ca i n fiierul original! (reamintim: nodurile
anonime au identificatori instabili ce nu pot s apar n interogri).

Executai o prim interogare n ecranul Query:


select * where {?x ?y ?z}

Aceasta va afia toate afirmaiile din baza de cunotine:

Executai cteva interogri SPARQL generice (fr semantic)

Extragerea tuturor subiectelor din baza de cunotine:


select ?x where {?x ?y ?z}

Extragerea de subiecte distincte din baza de cunotine:


select distinct ?x where {?x ?y ?z}

Extragerea de afirmaii ordonate dup proprietate:


select * where {?x ?y ?z} order by ?y

Extragerea primelor 10 afirmaii ordonate dup subiect:


select * where {?x ?y ?z} order by ?x limit 10
Executai cteva interogri SPARQL cu semantic simpl

La folosirea identificatorilor de tip URI ntr-o interogare, toate prefixele trebuie s fie declarate nainte
de interogare . Pentru a face acest lucru mai uor, procedai n felul urmtor :

Verificai opiunea Namespaces din meniul situat n partea stng Sesame. Toate prefixele care
au fost detectate n fiierul original ar trebui s apar listate acolo. De asemenea, se pot aduga
altele noi;
n unele versiuni de Sesame, n fereastra Query se poate apsa Clear. Aceast aciune ar trebui
s aduc n fereastra de interogri toate declaraiile de prefix ce s-au definit n Namespaces.
n alte versiuni, trebuie s ncepei s tastai "prefix" n fereastra Query i vei obine o list
derulant de prefixe (tot din lista de la Namespaces) pentru a alege pe cele de care avei nevoie

Pentru fiecare interogare, trebuie s v asigurai c prefixele sunt incluse la nceput dup cum arat
exemplul de mai jos (n restul exemplelor, prefixul va fi omis n acest document, dar voi trebuie s l
avei):

n ce filme a jucat Arnold?


prefix : <http://expl.at#>
select ?x
where
{
:Arnold :playedIn ?x
}

Cu ce are Arnold alte relaii dect :playedIn?


select ?x
where
{
:Arnold !:playedIn ?x
}
(avertisment: a nu se confunda cu negaia - nu se vor obine filmele n care NU a jucat Arnold! Vei
obine toate obiectele cu care Arnold are alt relaie dect :playedIn)

Afieaz tot ce este n relaie cu Terminator:


select ?x ?y
where
{
?x ?y :Terminator
}

Afieaz tot ce este n relaie cu Terminator i n plus afieaz Terminator pentru fiecare rezultat:
select ?x ?y (:Terminator as ?z)
where
{
?x ?y :Terminator
}

Afieaz tot ceea ce are nume, mpreun cu numele acestora:


select ?x ?y
where
{
?x :hasName ?y
}

Executai cteva interogri SPARQL cu filtre

Aceeai interogare ca i cea anterioar, dar s se afieze doar acele rezultate care au numele disponibil
n francez:
select ?x ?y
where
{
?x :hasName ?y
filter (lang(?y)="fr")
}

Afieaz tot ce are buget mai mic dect 10000000:


select ?x ?b
where
{
?x :hasBudget ?b
filter (?b<10000000)
}

Cine are ziua de natere 1947-07-10?


select ?x ?d
where
{
?x :birthInfo/:date ?d
filter (?d="1947-07-10"^^xsd:date)
}
(trebuie s traversm att :birthInfo ct i :date datorit nodului anonim care grupeaz data i locul)

Cine este cel al crui nume se termin n "on" (indiferent c e majuscul sau minuscul)?
select ?x
where
{
?x :hasName ?nm
filter regex(?nm,"ON$","i")
}
(regex permite s se aplice filtre cu expresii regulate!)

Care URI se termin n "on" (indiferent de tipul de liter)?


select ?x
where
{
?x :hasName ?nm
filter regex(str(?x),"ON$","i")
}
De aceast dat regex nu se aplic irurilor de caractere (nume, etichete) ci identificatorilor (URI-urilor)
iar rezultatele vor fi diferite. A se observa c identificatorii trebuie s fie convertii n iruri de caractere
cu str pentru a li se aplica testul regex! Aceast tehnic este folositoare pentru a detecta anumii
identificatori care aparin anumitor adrese de domeniu.

S se afieze toate afirmaiile pentru care obiectul este valoare simpl:


select *
where
{
?x ?y ?z
filter isliteral(?z)
}

Sunt disponibile funcii similare pentru verificarea dac un termen este URI (isuri) sau dac este nod
anonim (isblank).

S se afieze toate afirmaiile care au Terminator ca subiect SAU ca obiect:


select *
where
{
?x ?y ?z
filter ((?x=:Terminator)||(?z=:Terminator))
}

Ali conectori logici disponibili sunt && (conjuncia) i ! (negaia)

Executai cteva interogri SPARQL care returneaz expresii

S se construiasc o afirmaie n limbaj natural ce indic bugetul fiecrui film.


select (concat(?t," has a budget of ",str(?b)) as ?sentence)
where
{
?x :hasTitle ?t; :hasBudget ?b
}
(aceast tehnic poate fi folosit pentru a construi stringuri gata de afiat n cadrul unei interfee cu
utilizatorul!)

S se extrag prenumele oricui are un nume:


select (strbefore(?y," ") as ?firstname)
where
{
?x :hasName ?y
}

S se afieze filmele cu bugetele lor, plus un comentariu indicnd dac este un buget mic (sub
10000000) sau mare:
select ?x (if(?b<10000000,"Low budget","Big budget") as ?comment)
where
{
?x :hasBudget ?b
}
S se afieze bugetul mediu:
select (avg(?b) as ?AverageBudget)
where
{
?x :hasBudget ?b
}
(alte funcii de agregare disponibile sunt: count, sum, min, max, group_concat(concatenare de iruri),
sample (selectare arbitrar dintr-o list de valori))

S se construiasc un string n care se nir toate titlurile separate de virgul:


select (group_concat(?t;separator=', ') as ?TitleList)
where
{
?x :hasTitle ?t
}

S se afieze toi regizorii i numrul de filme pe care le-au regizat:


select ?x (count(?m) as ?MovieCount)
where
{
?x :directorOf ?m
}
group by ?x
(avertisment: o interogare cu grupare poate afia doar variabilele folosite n clauza GROUP BY (n cazul
nostru ?x) sau variabile agregate (aici ?MovieCount))

Aceeai interogare ca i cea anterioar, ns pstrnd doar regizorii care au mai mult de un film:
select ?x (count(?m) as ?MovieCount)
where
{
?x :directorOf ?m
}
group by ?x
having (?MovieCount>1)

S se afieze cte un exemplu de film pentru fiecare regizor:


select ?x (sample(?m) as ?Example)
where
{
?x :directorOf ?m
}
group by ?x

Construii o list de titluri pentru fiecare regizor care are mai mult de un film:
select ?x (group_concat(?t;separator=', ') as ?TitleList)
where
{
?x :directorOf/:hasTitle ?t
}
group by ?x
having (count(?t)>1)
(Observai cum proprietile :directorOf/:hasTitle sunt nlnuite pentru a lega regizorii de titluri)
Executai interogri SPARQL cu subinterogri

S se afieze filmul cu bugetul minim.


select ?minbfilm ?minb
where
{
?minbfilm :hasBudget ?minb
{select (min(?y) as ?minb) where {?x :hasBudget ?y}}
}
Acest exemplu se execut n 2 pai:

Prima dat (n subinterogare) se gsete bugetul minim i se pstreaz ntr-o variabil (?minb)
Apoi (n interogarea principal) se caut filmul cu bugetul respectiv

Pentru a transfera rezultatul de la subinterogare la interogarea principal s-a folosit o variabil comun
(?minb).

Executai interogri SPARQL contextuale (cu grafuri identificate)

Pentru a putea realiza acest lucru, avem nevoie de cel puin 2 contexte (grafuri identificate). Creai un
nou fiier movies2.trig cu urmtorul coninut:
@prefix : <http://expl.at#>.
:mynewmoviegraph
{:Titanic :directedBy :JamesCameron;
:hasActor :LeoDiCaprio.
:Godzilla :directedBy :REmmerich.
:DieHard :hasActor :BruceWillis.
:JamesCameron :directorOf :Terminator.
:Predator :hasBudget 100 .
:Titanic :hasBudget 200 .
:DieHard :hasBudget 300 .
:Godzilla :hasBudget 400 .
_:somemovie :hasBudget 500 .
}

Observai urmtoarele:

Relaia regizor-film este acum exprimat n dou moduri diferite (:directedBy i :directorOf).
Deocamdat Sesame nu nelege c aceste relaii sunt reciproc inverse! (e necesar utilizarea
terminologiei standard OWL pentru a face posibil acest lucru);
Am adugat cteva afirmaii care contrazic afirmaiile din graful iniial, de exemplu bugetul
filmului Predator. Se va putea detecta aceast contradicie tot prin raionare pe baza
standardului OWL, de care ne ocupm mai trziu (exist un mod standard de a spune c un film
nu poate avea dou bugete);
Dei s-a folosit un identificator pentru nod anonim _:somemovie cnd s-a ncrcat primul fiier,
ulterior a primit un nou ID i astfel s-a pierdut legtura cu afirmaiile anterioare (putei vedea
toate afirmaiile n ecranul Export).
ncrcai noul fiier n aceeai baz de cunotine i testai urmtoarele interogri:

S se afieze toate afirmaiile despre James Cameron, mpreun cu graful de care aparin:
select *
where
{
graph ?g {?x ?y ?z filter (?x=:JamesCameron)}
}
(observai c apare de dou ori afirmaia c James Cameron a regizat Terminator acest lucru este
permis deoarece e stocat n grafuri diferite; n cadrul aceluiai graf, o afirmaie poate apare o singur
dat!).

S se afieze toate afirmaiile din graful nou ncrcat:


select *
from :mynewmoviegraph
where {?x ?y ?z}

Aceleai rezultate pot fi obinute prin formularea de mai jos:


select *
where
{
graph :mynewmoviegraph {?x ?y ?z}
}

Deosebiri:

Cu clauza FROM, se va separa primul graf de restul cunotinelor i apoi se execut interogarea
pe graf
Cu clauza GRAPH se execut interogarea pe tot setul de date i apoi se filtreaz rezultatele dup
graful indicat

n cele mai multe cazuri rezultatele sunt identice. Dac se folosesc deodat, FROM are prioritate. Totui
se prefer clauza GRAPH deoarece permite interogri ce nu sunt posibile cu clauza FROM, precum:

- folosirea identificatorului de graf ca variabil (s se extrag toate afirmaiile despre Predator, inclusiv
numele grafului de care aparin)
select *
where
{
graph ?g {?x ?y ?z}
filter (?x=:Predator)
}

-combinarea abloanelor din grafuri diferite (s se extrag toate afirmaiile din graful iniial, despre cel
care a regizat Titanic conform grafului nou)
select *
where
{
graph :mynewmoviegraph {:Titanic :directedBy ?x}
graph :mymoviegraph {?x ?y ?z}
}
A se observa variabila comun ?x care realizeaz nlnuirea afirmaiilor din diferite grafuri.

S se compare ultimul rezultat cu urmtorul (toate afirmaiile despre cel care a regizat Titanic, conform
grafului nou):
select *
where
{
graph :mynewmoviegraph {:Titanic :directedBy ?x}
?x ?y ?z
}

i cu urmtorul (toate afirmaiile din noul graf, despre cel care a regizat Titanic conform aceluiai graf):
select *
where
{
graph :mynewmoviegraph {:Titanic :directedBy ?x. ?x ?y ?z}
}

S se afieze toate subiectele i proprietile folosite mpreun n ambele grafuri:


select distinct ?x ?y
where
{
graph :mynewmoviegraph {?x ?y ?z}
graph :mymoviegraph {?x ?y ?c}
}
Aceast tehnic poate fi folosit pentru a descoperi dac aceeai proprietate are valori diferite (pentru
acelai lucru) n contexte diferite. Se poate folosi:

Pentru a agrega informaii incomplete din surse multiple (presupunnd c fiecare graf conine
informaii pariale)
Pentru a detecta contradicii (de exemplu verificnd dac aceeai proprietate, de exemplu ziua
de natere sau CNP-ul este declarat diferit n baze de cunotine diferite, cee ace poate indica un
caz de fraud!).

Executai cteva interogri SPARQL cu metadate

Pentru urmtorul exemplu creai un al treilea fiier numit metacontext.trig.


@prefix : <http://expl.at#>.
:metadata
{
:mymoviegraph :description "it should contain valid information";
:reputation 10;
:datasource <http://www.imdb.com>.
:mynewmoviegraph :description "not so sure about this information";
:reputation 7;
:datasource :Robert.
}
Observai cum cele dou grafuri anterior folosite pot fi la rndul lor descrise (sunt subiecte)! n general
grafurile se descriu pentru a oferi clienilor informaii legate de proveniena sau calitatea (reputaia) lor.
Astfel de descrieri de grafuri se mai numesc metadate i pot fi izolate n propriul lor graf, eventual
administrat de cu totul altcineva dect cele descrise, pentru a asigura independena.
Acum putem s filtrm rezultatele dup reputaia fiecrui graf:

S se afieze toate informaiile disponibile despre James Cameron, ns doar din graful cu reputaia 10:
select *
where
{
graph :metadata {?x :reputation 10}
graph ?x {:JamesCameron ?b ?c}
}

Aceleai rezultate pot fi obinute dac realizm un filtru peste grafuri:


select ?x ?b ?c
where
{
graph :metadata {?x :reputation ?z}
graph ?x {?a ?b ?c}
filter ((?a=:JamesCameron)&&(?z=10))
}