Wstęp do Technologii Semantycznych SPARQL 1
Co to jest SPARQL? Skrót SPARQL to akronim od SPARQL Protocol and RDF Query Language. Jest to język zapytań dla formatu RDF nie ogranicza się jednak do RDF wiele innego rodzaju danych może być traktowanych jak RDF. SPARQL Informacja http://www.w3.org/tr/rdf-sparql-query/ 2
Co to jest SPARQL? w języku SPARQL mają zwykle standardową postać: I want these pieces of information from the subset of the data that meets these conditions Warunki o których mowa opisywane są za pomocą tzw. triple patterns. Triple patterns przypominają zwykłe stwierdzenia RDF z tą różnicą, że mogą w nich występować zmienne (rozpoczyjące się od?). 3
Szablon zapytania: SELECT co FROM skąd warunek Warunek ma zwykle postać: { } s1 p1 o1. s2 p2 o2. s3 p3 o3.... triple patterns W miejsce elementów stwierdzeń mogą pojawiać się zmienne np.?s1,?p3 itd, 4
Za pomocą pobieramy dane. Za pomocą SELECT decydujemy co chcemy mieć pokazane. 5
Endpoint Źródło danych RDF określone po FROM może być podane wprost w zapytaniu: FROM <data.ttl> bądź ustawione domyślnie. Każdy zbiór danych RDF dostępny online posiada zwykle tzw. endpoint czyli serwis akceptujący zapytania SPARQL i zwracający wyniki.
Endpoint http://www.w3.org/wiki/sparqlendpoints
Endpoint http://dbpedia.org/sparql
Endpoint http://labs.mondeca.com/endpoint/lov
SPARQL online? http://librdf.org/query
SPARQL lokalnie np. z wykorzystaniem RDF PHP API (ograniczenia)
SPARQL lokalnie Skrypt PHP: <?php if($_get['query']!="") { $querystring = $_GET['query']; define("rdfapi_include_dir","d:/xampp/rdfapi-php/api/"); include(rdfapi_include_dir. "RDFAPI.php"); $data = ModelFactory::getDefaultModel(); $data->load('data.rdf'); $result = $data->sparqlquery($querystring); echo $data->sparqlquery($querystring,'html'); }?>
SPARQL lokalnie Twinkle: A SPARQL Query Tool
Podstawy
Dane @prefix ab: <http://lsql.com/ns#>. ab:richard ab:hometel "(229) 276-5135". ab:richard ab:email "richard49@hotmail.com". ab:cindy ab:hometel "(245) 646-5488". ab:cindy ab:email "cindym@gmail.com". ab:craig ab:hometel "(194) 966-1505". ab:craig ab:email "craigellis@yahoo.com". ab:craig ab:email "c.ellis@usairwaysgroup.com".
Interesują nas wszystkie stwierdzenia z bazy. SELECT?s?p?o {?s?p?o. } SELECT * {?s?p?o. }
Wynik
Interesują nas orzeczenia wszystkich stwierdzeń z bazy. Zapytanie: SELECT?p {?s?p?o. }
Interesują nas (różne) orzeczenia stwierdzeń z bazy. Zapytanie: SELECT DISTINCT?p {?s?p?o. }
Interesuje nas stwierdzenie z określonym obiektem. Zapytanie: SELECT * {?s?p "(245) 646-5488" }
Interesuje nas email Craiga. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?craigEmail { ab:craig ab:email?craigemail. }
UWAGA: Oznaczenia prefixów nie mają znaczenia! Zapytanie: PREFIX b: <http://lsql.com/ns#> SELECT?craigEmail { b:craig b:email?craigemail. }
Interesuje nas osoba (zasób!) o określonym numerze telefonu. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?person {?person ab:hometel "(229) 276-5135". }
Wyniki zrozumiałe dla ludzi
Dane @prefix ab: <http://lsql.com/ns#>. @prefix d: <http://lsql.com/dt#>. d:i0432 ab:firstname "Richard". d:i0432 ab:lastname "Mutt". d:i0432 ab:hometel "(229) 276-5135". d:i0432 ab:email "richard49@hotmail.com". d:i9771 ab:firstname "Cindy". d:i9771 ab:lastname "Marshall". d:i9771 ab:hometel "(245) 646-5488". d:i9771 ab:email "cindym@gmail.com". d:i8301 ab:firstname "Craig". d:i8301 ab:lastname "Ellis". d:i8301 ab:email "craigellis@yahoo.com". d:i8301 ab:email "c.ellis@usairwaysgroup.com".
Interesuje nas email osoby o imieniu Craig. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?craigEmail {?person ab:firstname "Craig".?person ab:email?craigemail. }
Interesuje nas email osoby o imieniu Craig i nazwisku Ellis. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?craigEmail {?person ab:firstname "Craig".?person ab:lastname "Ellis".?person ab:email?craigemail. }
UWAGA: W triple patterns możemy stosować sktóry znane z Turtle. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?craigEmail {?person ab:firstname "Craig" ; ab:lastname "Ellis" ; ab:email?craigemail. }
Interesuje nas imię i nazwisko osoby o numerze telefonu domowego (229) 276-5135 Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last {?person ab:hometel "(229) 276-5135" ; ab:firstname?first ; ab:lastname?last. }
Interesują nas orzeczenia i obiekty stwierdzeń w których podmiot ma imię Cindy i nazwisko Marshall Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?propertyName?propertyValue {?person a:firstname "Cindy".?person a:lastname "Marshall".?person?propertyName?propertyValue. }
Interesują nas stwierdzenia w których obiekt zawiera ciąg znaków "yahoo" Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT * {?s?p?o. FILTER(regex(?o,"yahoo","i")) }
Problemy Interesują nas email i telefon domowy Craiga Ellisa. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?craigEmail?homeTel {?person ab:firstname "Craig".?person ab:lastname "Ellis".?person ab:email?craigemail.?person ab:hometel?hometel. } UWAGA: Wszystkie triple patterns muszą być spełnione!!!
Wybór języka Interesują nas artyści i nazwy albumów wyprodukowanych Timbalanda Zapytanie: PREFIX d: <http://dbpedia.org/ontology/> PREFIX dbpedia: <http://dbpedia.org/resource/> SELECT?artistName?albumName {?album d:producer dbpedia:timbaland.?album d:musicalartist?artist.?album rdfs:label?albumname.?artist rdfs:label?artistname. }
Wybór języka
Wybór języka UWAGA: Możemy wprowadzić ograniczenie związane z językiem Zapytanie: PREFIX d: <http://dbpedia.org/ontology/> PREFIX dbpedia: <http://dbpedia.org/resource/> SELECT?artistName?albumName {?album d:producer :Timbaland.?album d:musicalartist?artist.?album rdfs:label?albumname.?artist rdfs:label?artistname. FILTER ( lang(?artistname) = "en" ) FILTER ( lang(?albumname) = "en" ) }
Wybór języka
Dane @prefix foaf: <http://xmlns.com/foaf/0.1/>. <http://www.learningsparql.com/ns/demo#i93234> foaf:nick "Dick" ; foaf:givenname "Richard" ; foaf:mbox "richard49@hotmail.com" ; foaf:surname "Mutt" ; foaf:workplacehomepage <http://www.philamuseum.org/> ; foaf:aimchatid "bridesbachelor".
Interesuje nas ludzki opis zasobu. Zapytanie: PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT?propertyLabel?value {?s?property?value.?property rdfs:label?propertylabel. }
Brakujące dane
Dane 2 @prefix ab: <http://lsql.com/ns#>. @prefix d: <http://lsql.com/dt#>. d:i0432 ab:firstname "Richard". d:i0432 ab:lastname "Mutt". d:i0432 ab:hometel "(229) 276-5135". d:i0432 ab:nick "Dick". d:i0432 ab:email "richard49@hotmail.com". d:i9771 ab:firstname "Cindy". d:i9771 ab:lastname "Marshall". d:i9771 ab:hometel "(245) 646-5488". d:i9771 ab:email "cindym@gmail.com". d:i8301 ab:firstname "Craig". d:i8301 ab:lastname "Ellis". d:i8301 ab:worktel "(245) 315-5486". d:i8301 ab:email "craigellis@yahoo.com". d:i8301 ab:email "c.ellis@usairwaysgroup.com".
Interesują nas imionam nazwiska i telefony służbowe. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last?workTel {?s ab:firstname?first ; ab:lastname?last ; ab:worktel?worktel. } UWAGA: Telefon służbowy posiada tylko jedna osoba!
UWAGA: Do zapytań możemy dodawać opcjonalne triple patterns. Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last?workTel {?s ab:firstname?first ; ab:lastname?last. OPTIONAL {?s ab:worktel?worktel. } }
Ale ostrożnie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last?workTel?nick {?s ab:firstname?first ; ab:lastname?last. OPTIONAL {?s ab:worktel?worktel ; ab:nick?nick. } }
Tak lepiej: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last?workTel?nick {?s ab:firstname?first ; ab:lastname?last. OPTIONAL {?s ab:worktel?worktel. } OPTIONAL {?s ab:nick?nick. } }
UWAGA: Kolejność opcjonalnych triple patterns ma znaczenie! PREFIX ab: <http://lsql.com/ns#> SELECT?first?last {?s ab:lastname?last. OPTIONAL {?s ab:nick?first. } OPTIONAL {?s ab:firstname?first. } }
Odwrotna kolejność: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last {?s ab:lastname?last. OPTIONAL {?s ab:firstname?first. } OPTIONAL {?s ab:nick?first. } }
Dane nie spełniające pewnych warunków
Brak informacji Zapytanie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last?workTel {?s ab:firstname?first ; ab:lastname?last ; ab:worktel?worktel. } UWAGA: Co w sytuacji gdy chcemy wypisać dane osób, które nie mają podanego numeru do pracy?
Rozwiązanie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last {?s ab:firstname?first ; ab:lastname?last. OPTIONAL {?s ab:worktel?worknum. } FILTER(!bound(?workNum)) }
Inne rozwiązanie: PREFIX ab: <http://lsql.com/ns#> SELECT?first?last {?s ab:firstname?first ; ab:lastname?last. NOT EXISTS {?s ab:worktel?worknum } }
Ograniczanie liczby wyników
Dane @prefix d: <http://lsql.com/dt#>. @prefix rdfs: <http://www.w3.org/2000/01/rdfschema#>. d:one rdfs:label "one". d:two rdfs:label "two". d:three rdfs:label "three". d:four rdfs:label "four". d:five rdfs:label "five". d:six rdfs:label "six".
Ograniczenie do 2. Zapytanie: PREFIX rdfs: <http://www.w3.org/2000/01/rdfschema#> SELECT?label {?s rdfs:label?label. } LIMIT 2
Pominięcie 3. Zapytanie: PREFIX rdfs: <http://www.w3.org/2000/01/rdfschema#> SELECT?label {?s rdfs:label?label. } OFFSET 3
Pominięcie 3 i ograniczenie do 1. Zapytanie: PREFIX rdfs: <http://www.w3.org/2000/01/rdfschema#> SELECT?label {?s rdfs:label?label. } OFFSET 3 LIMIT 1
Dane @prefix e: <http://lsql.com/ns#>. @prefix d: <http://lsql.com/dt#>. d:m40392 e:description "breakfast" ; e:date "2011-10-14T08:53" ; d:m40393 e:description "lunch" ; e:date "2011-10-14T13:19" ; e:amount 11.13. d:m40394 e:description "dinner" ; e:date "2011-10-14T19:04" ; e:amount 28.30. d:m40395 e:description "breakfast" ; e:date "2011-10-15T08:32" ; e:amount 4.32.
Dane d:m40396 e:description "lunch" ; e:date "2011-10-15T12:55" ; e:amount 9.45. d:m40397 e:description "dinner" ; e:date "2011-10-15T18:54" ; e:amount 31.45. d:m40398 e:description "breakfast" ; e:date "2011-10-16T09:05" ; e:amount 6.65. d:m40399 e:description "lunch" ; e:date "2011-10-16T13:24" ; e:amount 10.00. d:m40400 e:description "dinner" ; e:date "2011-10-16T19:44" ; e:amount 25.05.
Sortowanie: PREFIX e: <http://lsql.com/ns#> SELECT?description?date?amount {?meal e:description?description ; e:date?date ; e:amount?amount. } ORDER BY?amount
Sortowanie (odwrotne): PREFIX e: <http://lsql.com/ns#> SELECT?description?date?amount {?meal e:description?description ; e:date?date ; e:amount?amount. } ORDER BY DESC(?amount)
Znalezienie maksimum: PREFIX e: <http://lsql.com/ns#> SELECT (MAX(?amount) as?maxamount) {?meal e:amount?amount. }
Znalezienie średniej: PREFIX e: <http://lsql.com/ns#> SELECT (AVG(?amount) as?avgamount) {?meal e:amount?amount. }
Grupowanie: PREFIX e: <http://lsql.com/ns#> SELECT?p (COUNT(?p) AS?pTotal) {?s?p?o. } GROUP BY?p