Ontop
提供:TogoWiki
目次 |
概要
関係データベース(RDB)などの非RDFデータに対してSPARQLで問合せを可能とするミドルウェア。現バージョンは1.9。
導入するにあたりドキュメント、および動画のチュートリアルが用意されている。
- Java7必須 (ただし、マッピングファイルの生成にProtegeを使う場合)
- オントロジーとRDBスキーマを対応させるマップを生成するためにProtegeおよびそのontopプラグインを使うが、テキストエディタでも生成可能
- SPARQLによるアクセス手段としてsesameを使うことが可能 (jettyを想定したサーブレットアプリが提供されている[1])
- R2RML形式でのマッピングファイルの入出力に対応している[2]が、Protege経由
- マッピングファイルに基づいてRDFのダンプファイルを生成することも可能[3]
- クエリ処理能力についてベンチマークを実施済[4]
- RDBの他にもExcelやCSV、XMLなどの形式にも対応している[5]
-ontop-関係の全てのツール群を使えるようにするには、Protegeにプラグイン (Java7必須でJava6でもJava8でも不可) を入れた上に、各種関係データベース用のJavaドライバの適切な場所へのインストールとProtegeでの設定など、実際に使えるようにするまでの準備作業に手間がかかるのが難点ではあるが、RDBへのアクセスをSPARQLエンドポイント経由で行うことを実現するためだけであれば、比較的作業は容易。 なお、SPARQL1.1への対応については不十分な状況 (BH12.12/SPARQL11test#-ontop-_v1.9)である。
SPARQLでデータにアクセス可能とするまでの手順
ここではmysqlにデータが格納されていることを想定して作業する。 最低限必要なのは、SPARQLエンドポイントとして動作するパッケージと、マッピングファイル (拡張子は .obda)、そしてオントロジーファイル (拡張子は .owl) の3点。
まず、例として、PubMedデータの一部が格納されているデータベースsapporoを想定する。 そしてsapporoには以下の4テーブルが含まれるとする。
- 著者名を格納するAUTHORS
- 論文題目を格納するTITLES
- 所属組織情報を格納するPMID_AFFILIATION
- PubMedデータの生成された日にちを格納するPMID_CREATED
全てのテーブルのキーはPubMed IDであり、そのカラム名はPMIDであり、型はint(10) unsigned。 また、データ生成日を示すPMID_CREATEDテーブルにはCREATED_ATカラムにdatetime型の値が格納されているほかは、著者情報や論文題目など全ての値がtext型。
- AUTHORS
+---------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+------------------+------+-----+---------+-------+ | PMID | int(10) unsigned | NO | PRI | 0 | | | PDATE | varchar(64) | YES | MUL | NULL | | | AUTHORS | text | YES | MUL | NULL | | +---------+------------------+------+-----+---------+-------+
- TITLES
+-------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+-------+ | PMID | int(10) unsigned | NO | PRI | 0 | | | TITLE | text | NO | MUL | NULL | | +-------+------------------+------+-----+---------+-------+
- PMID_AFFILIATION
+-------------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+------------------+------+-----+---------+-------+ | PMID | int(10) unsigned | NO | MUL | 0 | | | AFFILIATION | text | NO | MUL | NULL | | +-------------+------------------+------+-----+---------+-------+
- PMID_CREATED
+------------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+------------------+------+-----+---------+-------+ | PMID | int(10) unsigned | NO | PRI | NULL | | | CREATED_AT | datetime | NO | | NULL | | +------------+------------------+------+-----+---------+-------+
オントロジーファイルの生成
SPARQLで検索対象となるデータセットのスキーマをowl形式で記述する。Protegeなどのオントロジーエディタを利用するなりemacsなどの一般のテキストエディタを利用して生成する。
今回の例では単純にPubMedIDを示すURIを:PubMedIDクラスのインスタンスとするほか、著者名、論文題目、所属組織情報、生成日はそれぞれ:authors、:title、:affiliation、:createdという4つのデータプロパティで表現する。
<?xml version="1.0"?> <!DOCTYPE rdf:RDF [ <!ENTITY owl "http://www.w3.org/2002/07/owl#" > <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" > <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" > <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" > ]> <rdf:RDF xmlns="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#" xml:base="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <owl:Ontology rdf:about="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo"/> <owl:DatatypeProperty rdf:about="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#affiliation"/> <owl:DatatypeProperty rdf:about="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#authors"/> <owl:DatatypeProperty rdf:about="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#created"/> <owl:DatatypeProperty rdf:about="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#title"/> <owl:Class rdf:about="http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#PubMedID"/> </rdf:RDF>
マッピングファイルの生成
続いて作成されたオントロジーとRDBのスキーマとの関係を規定するマッピングファイルを生成する。 マップファイル文法に従って記述。 今回は下記のような内容になる。
ここで、PrefixDeclarationはその名の通り、プレフィックスを定義し、SourceDeclarationはRDBシステムへのアクセス情報を記述する。 そしてMappingDeclarationにオントロジーとスキーマの関係を記述していく。 関係はmappingID、target、sourceの記述を単位とし、各項目は次の通り。
mappingIdは各関係を識別するための名前で自由に記述できる。 targetにはturtle形式にならう記法で、SPARQL検索対象とするRDFを規定する。 中括弧{}で括られた中に、続くsourceで記述するSQL文で使われる変数名を記述して具体的な関係が表現される。 基本的なクエリは問題なく記述できるが一部のサブクエリなどには対応していない。 記述可能なSQLクエリについてはこちらに書かれている。
[PrefixDeclaration] : http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo# [SourceDeclaration] sourceUri mysql@yayamamo@sv01 connectionUrl jdbc:mysql://localhost:3306/sapporo username <username> password <password> driverClass com.mysql.jdbc.Driver [MappingDeclaration] @collection [[ mappingId MAPID-c5d3231bb9ec4a7da051779de5c41789 target <http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/{ti.PMID}> a :PubMedID . source SELECT ti.PMID FROM TITLES as ti mappingId MAPID-aa357962062246a2923fd282e3c69fc2 target <http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/{ti.PMID}> :title {ti.TITLE}^^xsd:string . source SELECT ti.PMID,ti.TITLE FROM TITLES as ti mappingId MAPID-ec12206a16154251b94cd638b50d840c target <http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/{a.PMID}> :affiliation {a.AFFILIATION}^^xsd:string . source SELECT a.PMID,a.AFFILIATION FROM PMID_AFFILIATION as a, TITLES as ti WHERE a.PMID = ti.PMID mappingId MAPID-d4d23e073afa4588897d0b0e85d7a673 target <http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/{au.PMID}> :authors {au.AUTHORS}^^xsd:string . source SELECT au.PMID,au.AUTHORS FROM AUTHORS as au, TITLES as ti WHERE au.PMID = ti.PMID mappingId MAPID-adee41cec4b34ef4bc8eb8c2c2ab28e0 target <http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/{cr.PMID}> :created {cr.CREATED_AT}^^xsd:dateTime . source SELECT cr.PMID,cr.CREATED_AT FROM PMID_CREATED as cr, TITLES as ti WHERE cr.PMID = ti.PMID ]]
SPARQLエンドポイントの立ち上げ
実際にSPARQLでデータにアクセスできる環境を整える。 ここ(要登録)から「SPARQL end-point package」というJettyとSesame workbench、そしてRDBとの橋渡し役を果たすQuestがバンドルされているパッケージをダウンロードする。 これはJavaが実行可能な環境であれば直ぐに立ち上げ可能で、初期設定の状態では http://localhost:8080/openrdf-workbench/ にアクセスすることで動作確認が出来る。 詳しくはこちらに書かれている。
なお、実際のデータが格納されているRDBシステムに併せたJavaのドライバ (JDBC) が必要になるので、これを別途入手し、Sesameから参照可能な場所に展開しておく。 mysqlであれば、http://dev.mysql.com/downloads/connector/j/ から入手できる。その他のシステムについてはこちら。
続いて、オントロジーファイルとマッピングファイルを指定してレポジトリを作成することで作業は終わる。 詳しくはこちらに書かれている。
なお、Sesame Workbenchでリポジトリが問題なく作成されると、以下の通り、何もデータが含まれていないことを示す表示がなされる。これは実際のデータがRDBに格納されているためで、逆に不具合がある場合は、"0"が表示される代わりにエラーが表示される。
Repository Size Number of Statements 0 Number of Labeled Contexts 0
そのほか、一連の作業中に問題が発生したときには判明済の問題点を確認する。
結果
試しに下記のクエリを発行する。
PREFIX : <http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#> SELECT * { ?s :created ?o . FILTER(?o < "2011-10-24") } ORDER BY ?o
得られるSQLクエリは以下の通り。
SELECT * FROM ( SELECT 1 AS "sQuestType", NULL AS "sLang", CONCAT('http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/', REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(CAST(QVIEW1.`PMID` AS CHAR(8000) CHARACTER SET utf8), ' ', '%20'),'!', '%21'),'@', '%40'),'#', '%23'),'$', '%24'),'&', '%26'),'*', '%42'), '(', '%28'), ')', '%29'), '[', '%5B'), ']', '%5D'), ',', '%2C'), ';', '%3B'), ':', '%3A'), '?', '%3F'), '=', '%3D'), '+', '%2B'), ', '%22'), '/', '%2F')) AS `s`, 8 AS "oQuestType", NULL AS "oLang", CAST(QVIEW1.`CREATED_AT` AS CHAR(8000) CHARACTER SET utf8) AS `o` FROM PMID_CREATED QVIEW1, TITLES QVIEW2 WHERE (QVIEW1.`PMID` = QVIEW2.`PMID`) AND QVIEW1.`PMID` IS NOT NULL AND QVIEW1.`CREATED_AT` IS NOT NULL AND (QVIEW1.`CREATED_AT` < '2011-10-24') ) SUB_QVIEW ORDER BY SUB_QVIEW.`o`
そしてこれに対するmySQLでの結果は以下の通り。
+------------+-------+---------------------------------------------------------------------------+------------+-------+---------------------+ | sQuestType | sLang | s | oQuestType | oLang | o | +------------+-------+---------------------------------------------------------------------------+------------+-------+---------------------+ | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000001 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000054 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000053 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000052 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000051 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000050 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000049 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000048 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000047 | 8 | NULL | 2011-10-17 00:00:00 | | 1 | NULL | http://uri.dbcls.rois.ac.jp/yayamamo/ontologies/2015sapporo#pmid/22000055 | 8 | NULL | 2011-10-17 00:00:00 | +------------+-------+---------------------------------------------------------------------------+------------+-------+---------------------+
このことから、結果にURIが含まれるときには、それをエンコードする部分までを含めたSQLクエリが発行されていることが分かる。また、explainすると以下の通りとなることから、SQLとしては非効率なクエリになりうるので、SQL側でのインデックスの工夫などが必要となりそう。こちらに検索効率を向上させるための様々なヒントが書かれている。
+----+-------------+------------+--------+---------------+------+---------+---------------------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+--------+---------------+------+---------+---------------------+------+----------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 40 | Using filesort | | 2 | DERIVED | QVIEW1 | ALL | PMID,X_PMID | NULL | NULL | NULL | 100 | Using where | | 2 | DERIVED | QVIEW2 | eq_ref | PMID | PMID | 4 | sapporo.QVIEW1.PMID | 1 | Using index | +----+-------------+------------+--------+---------------+------+---------+---------------------+------+----------------+