概要
RDF::LinkedData モジュールを利用し、LinkedData 用途の RDF (Resource Description Framework) を格納するサーバを構築する。
インストール
Ubuntu 14.04 LTS 環境で実行したところ、依存関係で 165 個くらいの perl モジュールがインストールされます。
非常にラクだがバージョンが 0.58 と古いので、数分程度時間がかかるかもしれませんが、最新版をインストールしたい場合は cpanm RDF::LinkedData しておくと良いかと思います。
以下のように出力されればインストール完了です。38 個の モジュールが更新され、0.58 -> 0.74 にアップグレードされます。
...
Successfully installed RDF-LinkedData-0.74 (upgraded from 0.58)
38 distributions installed
また、perlrdf コマンドラインツールも併せてインストールしておくと良いでしょう。
$ sudo apt-get install librdf-linkeddata-perl
$ sudo apt-get install cpanminus
$ sudo cpanm RDF::LinkedData
$ sudo apt-get install perlrdf
動作確認
動作確認用データとして、DBpedia のサイトから jawiki-20160407-article-categories.ttl.bz2 をダウンロードして展開します。
linked_data.psgi は上記手順でインストールを完了した場合、以下のパスにあります。
/usr/local/bin/linked_data.psgi
/usr/share/doc/librdf-linkeddata-perl/examples/linked_data.psgi
README の例には .ttl をメモリにロードして利用するワンライナーが紹介されているのですが、実行してみると以下のような Plack のエラーが返されてしまいました。
URL must be absolute ~というエラー内容なので、plackup -host http://localhost とか plackup -host http://127.0.0.1 のような指定は試行したが結果はかわらなかったことを補足しておく。
# PERLRDF_STORE="Memory;/home/daisuke/jawiki-20160407-article-categories.ttl" plackup -host localhost /usr/local/bin/linked_data.psgi
Error while loading /usr/local/bin/linked_data.psgi: 400 URL must be absolute at /usr/share/perl5/Plack/Util.pm line 134.
そのため、ひとまず SQLite に RDF を格納してから利用する方法を試してみることにしました。store_load が結構時間かかります(2時間半くらい。。)ので気長に待ちます。
SQLite に格納した場合は正常に起動したことから、やはりデータ量が多いと .ttl をロード中に plackup 未完全のままアクセスして 400 になるのではないかと思われる(推測)。
$ wget http://ja.dbpedia.org/dumps/20160407/jawiki-20160407-article-categories.ttl.bz2
$ bunzip2 -d jawiki-20160407-article-categories.ttl.bz2
$ export PERLRDF_STORE="DBI;mymodel;DBI:SQLite:database=rdf.db"
$ perlrdf make_store
$ perlrdf store_load ./jawiki-20160407-article-categories.ttl
$ plackup -host localhost /usr/local/bin/linked_data.psgi
HTTP::Server::PSGI: Accepting connections at http://localhost:5000/
データベーススキーマ
テーブル定義は以下のような感じになっている。Resources テーブルに 100 万件くらいのレコードが格納されています。
$ sqlite3 rdf.db
SQLite version 3.8.2 2013-12-06 14:53:30
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
CREATE TABLE Literals (
ID NUMERIC(20) PRIMARY KEY,
Value text NOT NULL,
Language text NOT NULL DEFAULT '',
Datatype text NOT NULL DEFAULT ''
);
CREATE TABLE Resources (
ID NUMERIC(20) PRIMARY KEY,
URI text NOT NULL
);
CREATE TABLE Bnodes (
ID NUMERIC(20) PRIMARY KEY,
Name text NOT NULL
);
CREATE TABLE Models (
ID NUMERIC(20) PRIMARY KEY,
Name text NOT NULL
);
CREATE TABLE Statements1304315348101281683 (
Subject NUMERIC(20) NOT NULL,
Predicate NUMERIC(20) NOT NULL,
Object NUMERIC(20) NOT NULL,
Context NUMERIC(20) NOT NULL DEFAULT 0,
PRIMARY KEY (Subject, Predicate, Object, Context)
);
sqlite> select count(*) from Resources;
1152974
sqlite> .q
そして、ようやく plackup でサーバは起動したもののいざアクセスしてみても 404: Unknown resource が返された。
そのため、linkeddata.json という設定ファイルを作成して export してみることにする。今度はエラーは返らないが応答も返らない。。サンプルデータでかすぎるのかな。。

Error while loading /usr/local/bin/linked_data.psgi: 400 URL must be absolute at /usr/share/perl5/Plack/Util.pm line 134.
$ vi rdf_linkeddata.json
$ cat rdf_linkeddata.json
{
"base_uri" : "http://localhost:5000/",
"store" : {
"storetype" : "DBI",
"name" : "mymodel",
"dsn" : "dbi:SQLite:dbname=rdf.db",
"username" : "",
"password" : ""
},
"endpoint": {
"html": {
"resource_links": true
}
},
"cors": {
"origins": "*"
},
"void": {
"pagetitle": "VoID Description for my dataset"
},
"expires" : "A86400" ,
"fragments" : {
"fragments_path" : "/fragments" ,
"allow_dump_dataset" : 0
}
}
$ export RDF_LINKEDDATA_CONFIG=./rdf_linkeddata.json
$ plackup /usr/local/bin/linked_data.psgi --host localhost --port 5000
というわけで、簡単なサンプル RDF を作成してから plackup すると無事データを参照することができました。
$ vi sample.ttl
$ cat sample.ttl
"Alice" .
.
_:Charlie .
.
# Here is a comment line.
"Bob" .
_:Charlie "Charlie" .
"David" .
$ vi rdf_linkeddata.json
$ cat rdf_linkeddata.json
{
"base_uri" : "http://localhost:5000/",
"store" : {
"storetype" : "Memory",
"sources" : [ {
"file" : "sample.ttl",
"syntax" : "turtle"
} ]
},
"endpoint": {
"html": {
"resource_links": true
}
},
"cors": {
"origins": "*"
},
"void": {
"pagetitle": "VoID Description for my dataset"
},
"expires" : "A86400" ,
"fragments" : {
"fragments_path" : "/fragments" ,
"allow_dump_dataset" : 0
}
}
$ export RDF_LINKEDDATA_CONFIG=./rdf_linkeddata.json
$ plackup /usr/local/bin/linked_data.psgi --host localhost --port 5000

RDF::LinkedData データセットが表示された
ようやく成功しました。テスト用には小さなサンプルデータを利用した方が良さそうですね。
SPARQL エンドポイントを利用するためにはモジュールを追加する必要があるので次回以降やっていくことにします。
参考資料
http://cpansearch.perl.org/src/KJETILK/RDF-LinkedData-0.74/README
[amazonjs asin=”4764904276″ locale=”JP” title=”Linked Data: Webをグローバルなデータ空間にする仕組み”]