Virtuoso(OSS版) dockerを立ち上げる。
RDFとSPARQLの勉強のために、SPARQLサーバの設定を行ったときのメモ。
VirtuosoはOPENLINK SOFTWARE社製のSPARQLサーバで、割と人気があるようなのでこれを使用する。
dockerにもいくつか環境が登録されているようだ。OFFICIALのイメージは無い。
環境は CentOS 7.3.1611、docker-1.12.6
環境構築
イメージの取得
後から、同じ環境を再現するために、基本、タグ付きでイメージを取得する。
$ docker search Virtuoso
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/tenforce/virtuoso Docker for hosting Virtuoso. 27 [OK]
docker.io docker.io/tenforce/ods-virtuoso RDF triple store with 15 catalogs in dcat-ap 5 [OK]
docker.io docker.io/inutano/virtuoso Virtuoso Opensource 3 [OK]
docker.io docker.io/nicholsn/virtuoso 3 [OK]
docker.io docker.io/stain/virtuoso Virtuoso 7 (stable) Open Source Edition on... 2 [OK]
$ docker pull tenforce/virtuoso:1.1.1-virtuoso7.2.4
Digest: sha256:759e0de994078f3a59d32e1e868892d7a0e643b4452ef5f964bafe1fa5edae63
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/tenforce/virtuoso 1.1.1-virtuoso7.2.4 37254352698c 4 weeks ago 502.5 MB
Virtuoso起動
永続のための領域をVOLUME上に確保し、Virtuosoを起動する。起動オプションはDockerのページ
に記述されているものを参考にする。
$ docker volume create --name main-virtuoso-data
main-virtuoso-data
$ docker volume ls
DRIVER VOLUME NAME
local main-virtuoso-data
$ docker run -d --restart=always --name main-virtuoso \
-p 8890:8890 -p 1111:1111 \
-e DBA_PASSWORD=dba \
-e SPARQL_UPDATE=true \
-e DEFAULT_GRAPH=http://www.example.com/graph \
-v main-virtuoso-data:/data \
-d tenforce/virtuoso:1.1.1-virtuoso7.2.4
7f73ea2c9f38bb6c36b7ee56032d2647ee13522580ed716907a3bbb555eb2632
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f73ea2c9f38 tenforce/virtuoso:1.1.1-virtuoso7.2.4 "/bin/bash /virtuoso." 15 seconds ago Up 14 seconds 0.0.0.0:1111->1111/tcp, 0.0.0.0:8890->8890/tcp main-virtuoso
1111 がコマンドライン(isql-vt)用ポート
8890 がWebインタフェース用ポート番号
CentOS上のVirtuoso http://192.168.45.131:8890/ にアクセス。CentOSにはGUIをインストールしていないため、他よりアクセスする。
ホスト側のツールインストール
ホスト側にCUIツールをインストールする。これにより、CUIコマンド(isql-vt)が利用可能になる。
$ sudo yum install virtuoso-opensource-utils
RDFデータの登録方法
GUIからのデータ登録
VirtuosoにRDFデータをロード,SPARQLで検索を参考にしてデータを登録してみる。
http://192.168.45.131:8890/conductor/ にアクセスし、デフォルトのアカウント dba でログイン、パスワードはdocker起動時に指定したもの dba を指定する。
ログイン後、[Linked Data] – [Quad Store Upload]からデータのアップロード画面を開く。
参考にしたページはvirtuosoのバージョンが6.x系のためか「RDF」となっているが、使用するイメージは7.2.4では「Linked Data」となっている。
CUIからのデータ登録
DBPedia Japanが公開しているデータのなかから'20160407/jawiki-20160407-article-categories.ttl.bz2'を投入してみる。
読み込むテキストのフォーマットにより、パーサーを指定する必要がある。
- TTLP_MT ……… TTL (TURTLE), TTL(N-Triple) or NQ (N-quad)をパース
- RDF_LOAD_RDFXML_MT ……… RDF/XMLテキストをRDFトリプルのシーケンスとしてパース
ホスト上で読み込みコマンドを実行すると、以下のようなエラーになる。
$ isql-vt -U dba -P dba
SQL> DB.DBA.TTLP_MT (file_to_string_output ('jawiki-20160407-article-categories.ttl'), '', 'http://example.com/', 512);
*** Error 42000: [Virtuoso Driver][Virtuoso Server]FA112: Can't stat file 'jawiki-20160407-article-categories.ttl', error (2) : No such file or directory
straceコマンドでdocker上のVirstuosoサーバとクライアントコマンドをシステムコールをチェックすると、
TTLファイルは、docker上のVirstuosoサーバ側が参照しているため、ホストに配置したTTLファイルは見つからないのエラーとなる。
docker上にファイルを配置して、TTLファイルの読み込みを行う。
$ docker cp jawiki-20160407-article-categories.ttl main-virtuoso:/data/.
$ isql-vt -U dba -P dba
DB.DBA.TTLP_MT (file_to_string_output ('/data/jawiki-20160407-article-categories.ttl'), '', 'http://example.com/', 512);
*** Error 42000: [Virtuoso Driver][Virtuoso Server]FA003: Access to '/data/jawiki-20160407-article-categories.ttl' is denied due to access control in ini file
が、エラーとなる。どうやら読み込みを許可しているパスは、virstuoso.intファイル内で決まっているようだ。
DirsAllowed = ., /usr/local/virtuoso-opensource/share/virtuoso/vad
TTLファイルを許可されたディレクトリに移動し、再度読み込みを行う。
DB.DBA.TTLP_MT (file_to_string_output ('/usr/local/virtuoso-opensource/share/virtuoso/vad/jawiki-20160407-article-categories.ttl'), '', 'http://example.com/', 512);
Done. -- 74800 msec.
RDFデータの検索
GUIから登録したデータの検索
[Linked Data] – [SPARQL]からSPARQLクエリを入力し、「Execute」を押下し検索を実行する。
select ?o where {
<http://ja.dbpedia.org/resource/高橋留美子> ?p ?o
}
ブラウザより検索を実行。正常にロードできている。
CUIからデータの検索
ホストにインストールしたCUIコマンド(isql-vt)を使用してSPARQLクエリを実行する。
$ isql-vt -U dba -P dba
SQL> sparql select ?o where { <http://ja.dbpedia.org/resource/高橋留美子> ?p ?o } ;
o
LONG VARCHAR
_______________________________________________________________________________
http://ja.dbpedia.org/resource/Category:1957年生
http://ja.dbpedia.org/resource/Category:存命人物
http://ja.dbpedia.org/resource/Category:新潟市出身の人物
http://ja.dbpedia.org/resource/Category:日本の漫画家
http://ja.dbpedia.org/resource/Category:日本女子大学出身の人物
http://ja.dbpedia.org/resource/Category:高橋留美子
6 Rows. -- 58 msec.
SQL>
WebAPIからの検索
アプリから利用するためには、RESTかSOAPのやり取りを行う必要がある。
Virtuoso SPARQL Query Serviceでは、以下のように記載があるのでPOSTで試す。
Method | Notes |
---|---|
GET | Short queries are sent in GET mode |
POST | Queries longer than 1900 bytes are POST-ed |
ここにSOAPのサンプルが載っていたので試す。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<query-request xmlns="http://www.w3.org/2005/09/sparql-protocol-types/#">
<query xmlns="">
SELECT DISTINCT ?z WHERE { <http://ja.dbpedia.org/resource/高橋留美子> ?y ?z .} LIMIT 10
</query>
</query-request>
</soapenv:Body>
</soapenv:Envelope>
$ curl -d@soap.xml -H "Content-Type:text/xml" -H "SOAPAction: ''" http://192.168.45.131:8890/sparql/
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<query-result xmlns="http://www.w3.org/2005/09/sparql-protocol-types/#">
<sparql xmlns="http://www.w3.org/2005/sparql-results#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd">
<head>
<variable name="z"/>
</head>
<results distinct="false" ordered="true">
<result>
<binding name="z"><uri>http://ja.dbpedia.org/resource/Category:1957年生</uri></binding>
</result>
<result>
<binding name="z"><uri>http://ja.dbpedia.org/resource/Category:存命人物</uri></binding>
</result>
<result>
<binding name="z"><uri>http://ja.dbpedia.org/resource/Category:新潟市出身の人物</uri></binding>
</result>
<result>
<binding name="z"><uri>http://ja.dbpedia.org/resource/Category:日本の漫画家</uri></binding>
</result>
<result>
<binding name="z"><uri>http://ja.dbpedia.org/resource/Category:日本女子大学出身の人物</uri></binding>
</result>
<result>
<binding name="z"><uri>http://ja.dbpedia.org/resource/Category:高橋留美子</uri></binding>
</result>
</results>
</sparql></query-result></soapenv:Body></soapenv:Envelope>
SPARQL Guide for the Javascript Developer を見てみるとXMLでなくてもいけそうなので試してみる。
ただし、日本語の応答がエンコード(¥uXXXX)されているのでデコードする必要があった。
query=SELECT+DISTINCT+%3Fo+WHERE+%7B+%3Chttp%3A%2F%2Fja.dbpedia.org%2Fresource%2F%E9%AB%98%E6%A9%8B%E7%95%99%E7%BE%8E%E5%AD%90%3E+%3Fp+%3Fo%7D&format=application%2Fjson
$ curl -s -d@url.txt -H "Content-Type: application/x-www-form-urlencoded" 'http://192.168.45.131:8890/sparql/' | perl -Xpne 's/\\u([0-9a-fA-F]{4})/chr(hex($1))/eg'
{ "head": { "link": [], "vars": ["o"] },
"results": { "distinct": false, "ordered": true, "bindings": [
{ "o": { "type": "uri", "value": "http://ja.dbpedia.org/resource/Category:1957年生" }},
{ "o": { "type": "uri", "value": "http://ja.dbpedia.org/resource/Category:存命人物" }},
{ "o": { "type": "uri", "value": "http://ja.dbpedia.org/resource/Category:新潟市出身の人物" }},
{ "o": { "type": "uri", "value": "http://ja.dbpedia.org/resource/Category:日本の漫画家" }},
{ "o": { "type": "uri", "value": "http://ja.dbpedia.org/resource/Category:日本女子大学出身の人物" }},
{ "o": { "type": "uri", "value": "http://ja.dbpedia.org/resource/Category:高橋留美子" }} ] } }
後は、ブラウザ上のjavascriptアプリから検索できることを確認したい。
参考
- VirtuosoにRDFデータをロード,SPARQLで検索Add Star
- Virtuosoへのデータのロード方法(英語)
- Virtuosoを試す
- How to Install Virtuoso Open Source (VOS) on CentOS Linux
- Virtuosoを試す
- SPARQLthon19/TripleLoad
- Virtuoso SPARQL Query Service
- VirtuosoのCross-Origin Resource Sharing (CORS) 許可
- Cross-Origin Resource Sharing (CORS) enabling a Virtuoso SPARQL Endpoint