isql

    W poprzednim wpisie było o Semantic Web w sensie ogólnym. Skupialiśmy się na sposobie organizacji danych. W tym opiszę jak pobrać i załadować do Virtuoso dane udostępniane przez Project Gutenberg. Zaczniemy od tego że pobierzemy je z tej strony. Dane dostępne są w dwóch formatach, skupimy się na nowszym z nich. Format starszy jest wyraźnie gorszy do zabawy, jak ktoś jest ciekawy dlaczego, może także pobrać pliki z danymi, i załadować dane do Virtuoso w celu porównania. Po pobraniu plik należy rozpakować. Plik do pobrania nie jest szczególnie wielki – ma 13 Mb w wersji bz i 23 w wersji zip, wszakże po rozpakowaniu dostaniemy prawie 800 Mb danych, w plikach tekstowych poukładanych w ponad 44 tysiącach katalogów. Nazwa każdego katalogu odpowiada numerowi publikacji w Projekcie Gutenberg, a zawartość każdego katalogu to plik z rozszerzeniem rdf, zawierający opis pozycji. Przykładowo fragment pozycji 4147 jest następujący:

pg4047.rdf:
……………………
<dcterms:subject>
<rdf:Description>
<dcam:memberOf rdf:resource=”http://purl.org/dc/terms/LCC„/>
<rdf:value>PS</rdf:value>
</rdf:Description>
</dcterms:subject>
<dcterms:title>The Leavenworth Case</dcterms:title>
<dcterms:type>
<rdf:Description>
<dcam:memberOf rdf:resource=”http://purl.org/dc/terms/DCMIType„/>
<rdf:value>Text</rdf:value>
</rdf:Description>
</dcterms:type>
</pgterms:ebook>
<pgterms:agent rdf:about=”2009/agents/541″>
<pgterms:alias>Rohlfs, Anna Katharine Green</pgterms:alias>
<pgterms:alias>Rohlfs, Mrs. Charles</pgterms:alias>
<pgterms:birthdate rdf:datatype=”http://www.w3.org/2001/XMLSchema#integer„>1846</pgterms:birthdate>
<pgterms:deathdate rdf:datatype=”http://www.w3.org/2001/XMLSchema#integer„>1935</pgterms:deathdate>
<pgterms:name>Green, Anna Katharine</pgterms:name>
<pgterms:webpage rdf:resource=”http://en.wikipedia.org/wiki/Anna_Katharine_Green„/>
</pgterms:agent>
<rdf:Description rdf:about=”http://en.wikipedia.org/wiki/Anna_Katharine_Green„>
<dcterms:description>en.wikipedia</dcterms:description>
</rdf:Description>
…………………………

    W terminologii Virtuoso ( i Semantic Web) dane które pobierzemy – o zapisaniu w bazie danych – utworzą nie tabelę lecz graf. Nazwa ta bierze się z faktu, że dane które ładujemy to trójki, subject – predykat – object – <S,P,O>, a to z kolei można interpretować jako opis grafu gdzie subject i object to wierzchołki a predykat jest etykietą krawędzi. Aby załadować te dane należy skłonić Virtuoso do przeglądnięcia rekurencyjnie każdego z tych katalogów i pobrania do bazy danych z plików rdf. Instrukcja opisująca jak tego dokonać znajduje sie tu. W tym celu musimy utworzyć w katalogu głównym, tam gdzie „widać wszystkie katalogi”, plik o nazwie global.graph. W pliku tym podamy nazwę grafu do którego będziemy ładować dane. Wpisać można właściwie cokolwiek, ja zachowując pewną konwencję nadałem grafowi nazwę http://gutenberg.new czyli mój plik global.graph, zawierają tylko jedna, właśnie tą linię:

global,graph:
http://gutenberg.new

Następnie otwieramy sobie terminal i łączymy się z motorem Virtuoso za pomocą polecenia

isql-vt 1111 dba hasło

i wydajemy polecenie:

 SQL> ld_dir_all('/home/Semantic/cache/epub','*.rdf','http://gutenberg.new');

gdzie /home/Semantic/cache/epub to ścieżka do katalogów z danymi i należy oczywiście użyć takiej jaka jest w Waszym systemie. *.rdf określa rozszerzenie ( i format) plików które importujemy. Ostatni parametr to nazwa grafu. Powoduje ono zarejestrowanie „danych do importu”. Możemy sprawdzić operacja ta zakończyła sie sukcesem za pomocą polecenia:

 SQL> select from DB.DBA.load_list;

Jeśli wszystko poszło dobrze, powinniśmy zobaczyć 44 tysiące linii zawierających nazwy plików do importu. Pliki te można policzyć:

 SQL> select count(*) from DB.DBA.load_list;

Następnie ładujemy dane za pomocą polecenia:

SQL> rdf_loader_run();

Po zakończeniu importu ( u mnie trwał około 10 minut) możemy sprawdzić liczbę zaimportowanych trójek za pomocą polecenia sparql:

SQL> sparql select count(*) { graph <http://gutenberg.new> { ?s ?p ?o.}};
 callret-0
 INTEGER
 _______________________________________________________________________________
5421346
1 Rows. -- 2701 msec.

    Jak widać powstało prawie 5 i pół miliona rekordów. Gdyby coś poszło nie tak, możemy wyczyścić graf za pomoca polecenia:

 SQL> sparql clear graph <http://gutenberg.new>;

i przeprowadzić import jeszcze raz.

    Jeśli import przeszedł poprawnie, możemy zacząć analizę zawartości grafu. Poświęcony będzie temu zadaniu kolejny wpis, ten zakończmy jedynie podaniem listy predykatów ( etykiet krawędzi) jakie występują w zaimportowanych danych:

 SQL> sparql select distinct ?p from <http://gutenberg.new> where{ ?s ?p ?o.};
 p
 LONG VARCHAR
 _______________________________________________________________________________
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
 http://www.w3.org/1999/02/22-rdf-syntax-ns#_1
 http://www.w3.org/1999/02/22-rdf-syntax-ns#_2
 http://www.w3.org/1999/02/22-rdf-syntax-ns#_3
 http://purl.org/dc/terms/modified
 http://purl.org/dc/terms/extent
 http://purl.org/dc/terms/creator
 http://purl.org/dc/terms/subject
 http://purl.org/dc/terms/title
 http://web.resource.org/cc/license
 http://purl.org/dc/terms/issued
 http://purl.org/dc/terms/language
 http://purl.org/dc/terms/license
 http://purl.org/dc/terms/publisher
 http://purl.org/dc/terms/rights
 http://purl.org/dc/dcam/memberOf
 http://purl.org/dc/terms/type
 http://purl.org/dc/terms/description
 http://purl.org/dc/terms/hasFormat
 http://www.gutenberg.org/2009/pgterms/name
 http://purl.org/dc/terms/format
 http://www.gutenberg.org/2009/pgterms/alias
 http://www.gutenberg.org/2009/pgterms/birthdate
 http://www.gutenberg.org/2009/pgterms/deathdate
 http://www.gutenberg.org/2009/pgterms/webpage
 http://id.loc.gov/vocabulary/relatorstrl
 http://purl.org/dc/terms/tableOfContents
 http://id.loc.gov/vocabulary/relatorsedt
 http://purl.org/dc/terms/alternative
 http://www.gutenberg.org/2009/pgterms/marc010
 http://id.loc.gov/vocabulary/relatorsctb
 http://id.loc.gov/vocabulary/relatorsill
 http://id.loc.gov/vocabulary/relatorsaui
 http://www.gutenberg.org/2009/pgterms/marc901
 http://www.gutenberg.org/2009/pgterms/marc440
 http://id.loc.gov/vocabulary/relatorscmp
 http://id.loc.gov/vocabulary/relatorslbt
 http://id.loc.gov/vocabulary/relatorsprf
 http://id.loc.gov/vocabulary/relatorsarr
 http://id.loc.gov/vocabulary/relatorsunk
 http://id.loc.gov/vocabulary/relatorscom
 http://www.gutenberg.org/2009/pgterms/marc260
 http://id.loc.gov/vocabulary/relatorsoth
 http://id.loc.gov/vocabulary/relatorscnd
 http://www.w3.org/1999/02/22-rdf-syntax-ns#value
 http://purl.org/dc/terms/isFormatOf
 http://id.loc.gov/vocabulary/relatorsaft
 http://www.gutenberg.org/2009/pgterms/marc546
 http://id.loc.gov/vocabulary/relatorscmm
 http://id.loc.gov/vocabulary/relatorsann
 http://id.loc.gov/vocabulary/relatorspbl
 http://id.loc.gov/vocabulary/relatorsadp
 http://id.loc.gov/vocabulary/relatorsegr
 http://www.gutenberg.org/2009/pgterms/marc250
 http://www.gutenberg.org/2009/pgterms/marc508
 http://id.loc.gov/vocabulary/relatorsdub
 http://id.loc.gov/vocabulary/relatorspht
 http://www.gutenberg.org/2009/pgterms/marc520
 http://www.gutenberg.org/2009/pgterms/marc300
 http://www.gutenberg.org/2009/pgterms/marc902
 http://www.gutenberg.org/2009/pgterms/marc903
 http://id.loc.gov/vocabulary/relatorstrc
 http://id.loc.gov/vocabulary/relatorsart
 http://www.gutenberg.org/2009/pgterms/marc020
 http://www.gutenberg.org/2009/pgterms/marc653
 http://id.loc.gov/vocabulary/relatorsprt
 http://id.loc.gov/vocabulary/relatorsres
 http://id.loc.gov/vocabulary/relatorsclb
68 Rows. -- 10212 msec.

     Jak widać predykaty mają formę adresów URL ( co nie jest konieczne ale bywa praktyczne). W teorii każdy z tych adresów może być referencable co oznacza że można w niego kliknąć a po wyświetleniu w przeglądarce powinniśmy zobaczyć definicje czy opis o co w predykacie chodzi. W praktyce nie każda informacja jest dostępna czy aktualna. To wielka szkoda bo wiele spraw byłoby znacznie prostszych gdyby zachowano ta konwencję. Ważnym i działający fragmentem tej struktury sa adresy podobne do tego: http://purl.org/dc/terms/language . Odwołują sie one do tzw. Dublin Core Initiative – proponowanego standardu opisu metadanych dotyczących dokumentów.

    Na dziś to wszystko. W kolejnym wpisie pobawimy się SPARQL – językiem stworzonym w celu efektywnego budowania zapytań w bazach danych zawierających grafy.