data/rdf
wikibase で rdf/turtle 出力するとき。/wiki/Special:EntityData/Q1.ttl などにアクセスすればよい。
wd:
や p:
などの prefix を固定するときは、次のように conceptBaseUri
を指定するとよい
$wgWBRepoSettings["conceptBaseUri"] = "https://example.jp/entity/";
data:
などの自己参照は、Wikibase extension レベルでどうこうするところはなさそうで、次のように mediawiki 設定を変更する。
$wgCanonicalServer = "https://example.jp";
ただし https://phabricator.wikimedia.org/T241975 でまた挙動がかわる
wikibase で出てくる entityNamespace 120, 122 は、wikibase の名前空間というよりは、mediawiki の名前空間で、/w/api.php の rcnamespaces で使われる。
triple store の選定のためのヒント集
- https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/WDQS_backend_update/WDQS_backend_alternatives
- https://www.semantic-mediawiki.org/wiki/Help:SPARQLStore
- https://www.w3.org/wiki/LargeTripleStores
- https://sparqlwrapper.readthedocs.io/en/latest/main.html#sparql-endpoint-implementations
Virtuoso は Commercial 版になると RDF replication できるようになる。
quad が使われる理由:tripleで知識が得られたとして、次にその主張を信じてよいのかが問題になる。その検証には使用したtripleの出典が問題になる。自然と triple に出典・来歴をくっつけた形で扱うことが多くなるため、quad という形式で管理すると都合がよい。
実装上も、例えば更新頻度の異なるデータセットを分けて管理したい場合、名前空間のようなもので分離しておきたいと思うだろう。そういったときにもquadが有効になる。つきつめるとこれもデータの出元の問題となる。
出典付き triple は triple with provenance と呼ばれ、例えば blazegraph の設定例でも TRIPLES_MODE
, TRIPLES_MODE_WITH_PROVENANCE
, QUADS_MODE
が用意されていたりする。
あまり明言されない事をメモしておく
- クラス情報は必須ではない。無くてもデータに SPARQL できる。
- オントロジーでいうところの「推論」は一般的な意味の推論ではなく、コンパイラの「型推論」の意味。
-
rdf:type
をはじめとするクラス設計は、達成したい目標に向かってデータ作成者が設計する。一般的な話として、目標から外れた過剰な設計は必要ない。 - プログラミング言語で、単一継承、多重継承、ミックスインといった概念がある。これらと対応させて
rdf:type
を考えると良い。 - 初期段階ではデータベースやサーチエンジンは必要ない。turtle あるいは trig のプレーンテキストのファイルに SPARQL を行うシステムで必要十分。
- quad store は provenance に有効で、linked data として使うときに役に立つ。
- RDF は triple や quad という概念。Linked data はデータ結合をする世界観。二つのものは並列するものではなく、そもそも指し示しているものが異なる。
- RDF / Linked Data の機能や理念と実際のデータの乖離に消耗することはよくある。しかしながら Linked data が有効な局面は確かに存在するので、必要になったときにはじめて必要なだけ使えばよい。
Datasetという用語は、最初SPARQLで導入され、RDF関連の様々なところで顔を覗かせる。ただしDatasetはコンテキストによって意味するところが変わることに注意。
Virtuossoでは、Quadstoreであり、Datasetはデータを分割するもの。SPARQL query 時に名前を指定せずに query すると、全体をクエリすることができる。名前を指定すると、そのdataset内のgraphのみが検索される。SPARQL 1.1 updateのインターフェースからは、名前なしのDefault datasetにtripleを保存することはできない(*1)。DELETE もdatasetの指定が必須で、どういうモデルを考えているのかがうかがえる(*2)。
*1) https://github.com/openlink/virtuoso-opensource/issues/417
*2) https://github.com/openlink/virtuoso-opensource/issues/215#issuecomment-48845476
rdflib
sparql 1.1 update の話
SPARQLWrapper が先行して対応し、rdflib の SPARQL 対応はゆっくりと進んできた。SPARQL 1.1 update は rdflib 本体でもできるようになってきた。
ただし現時点での SPARQLUpdateStore は少し変な状況にある。SPARQLConnector.update の実装を引き継げばいいように思えるのだけれど、独自な実装をしている。使う場合は database transaction のように commit, rollback で終わらせること。でないとゴミが残って、続く処理でおかしなことになる。
from rdflib import URIRef, Graph
g = Graph("SPARQLUpdateStore", "http://example.org/defaultGraphUri")
g.open("http://example.org/sparqlendpoint")
# USE add()
try:
g.add((URIRef("a:"), URIRef("b:"), URIRef("c:")))
g.commit()
except:
g.rollback()
# OR, update()
try:
g.update("INSERT DATA { <a:> <b:> <c:> . }")
g.commit()
except:
g.rollback()
virtuoso は HTTP GET
method で SPARQL 1.1 Update が実行できる(組み込みWebUIもこれを使ってる)。だから rdflib.Graph.update
ではなく rdflib.Graph.query
で SPARQL 1.1 Update が実行できて、SPARQLUpdateStore を回避することも可能。
fuseki/Jena の dockerfile は maven repo 経由で取得できるらしい(出典)。具体的な手順が書いてなかったけれども、次のコマンドが便利。
mvn dependency:get -Dartifact=org.apache.jena:jena-fuseki-docker:LATEST:zip -Ddest=.
あるいは普通に wget
でダウンロードしてもよさそう。
SOH cli utility は apache-jena-fuseki binary distribution(zip) をダウンロードして展開して PATH を通せばよさそう。ruby
が必要。
fuseki/jenaはSPARQL構文に厳密。virtuosoは、アルアルなエラーは見逃して解釈してくれる。おそらくサポートの都合もあって、歴史的なものを引きずってメンテナンスしてる。ある意味では偉い。
virtuoso は例えば次の構文を許す。
SELECT ?a, ?b WHERE { # 正しくは `SELECT ?a ?b`
?a ?b ?c .
} ORDER BY ?b, ?c # 正しくは ?b ?c
あるいは、SPARQL query で SPARQL update を流しても受け入れる。本来update=でupdate構文を送るところを、query= の中身として送っても処理される。
fuseki/jena を高可用性(HA)の構成にしようとすると、rdf-deltaの拡張版が見つかる。
delta-fuseki-server を実行すると、rdf の更新時に rdf patch 形式の差分を生成し、delta-server に送り込む。delta-server は全ての変更履歴を保持していて、ジャーナリングを行う。delta-fuseki-server はジャーナルから rdf を構築しなおして query に備える。
single でも動作させられる。HAにするには各ポイントを冗長化させる。delta-server は zookeeper で quorum を組んで動作する。
SemanticMediaWiki の SPARQLStore 設定、現時点(2023-06)では、正直 "default" connector だけでいい気がする。"virtuoso" も "fuseki" も使わなくていいんじゃない…?
ただし"data"
エンドポイントだけは、SemanticMediaWiki側がぶっ壊れているので空文字で無効化しておくこと。
rdflib
SPARQL endpoint が自己署名証明書な HTTPS だった時の話。一番簡単な「検証無視」な設定はデフォルトファクトリを置き換える方法。
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
import rdflib
g=rdflib.Graph("SPARQLUpdateStore")
g.open("https://selfsigned.sparql.endpoint.example.org/")
g.query('''
SELECT * WHERE { ?s ?p ?o . }
''')
jena fuseki を使っていて、トリプルを保存したはずなのに、どっかに行ってしまったと思った時。ひょっとして default graph に保存されているかも。
jena fuseki は quad store で、特殊機能として named graph を一つにまとめて見せる unionDefaultGraph
という機能 がある。注意点としては、名前のない default graph は Union されないという点。
jena fuseki の SPARQL は一般的に使われる query
以外に、SPARQL を拡張した SPARQL 1.1 UPDATE である update
や SPARQL Graph store protocol (GSP) の gsp-r
, gsp-rw
をサポートしている。
迷子になったときは次を試してみるとよい
- GSP get でデフォルトグラフを取得する
-
s-get
コマンドで operation=gsp-r なエンドポイントに問い合わせる
-
- デフォルトグラフを明示的に指定して SPARQL クエリする
-
特殊 URI である
urn:x-arq:DefaultGraph
を使う
-
特殊 URI である
SELECT * WHERE { GRAPH <urn:x-arq:DefaultGraph> { ?s ?p ?o . } }
SPARUL は、もともと hp で jena の機能として開発されていた SPARQL の拡張で、SPARQL/Update と表記されたりもするもの。
- https://www.hpl.hp.com/techreports/2007/HPL-2007-102.pdf (著者 https://twitter.com/AndySeaborne)
- これが virtuoso にも実装された https://docs.openlinksw.com/virtuoso/rdfsparul/
そのうちに w3c で標準化が進み、SPARQL-Update となった。SPARUL は祖先のバージョン違いと考えればよい。
ちなみに jena は hp から apache foundation に移管された
virtuoso の DBA_PASSWORD は 20 文字まで。それ以上の文字数を設定すると dba でログインできなくなり、操作不能に陥る。https://hub.docker.com/r/openlink/virtuoso-opensource-7 で確認。
SemanticMediaWiki で SemanticResultFormats を有効にすると、ask parser のテーブル出力を高機能な JavaScript ベースのdatatablesで操作できるようになる。
注意点
- 現時点ではSearchPanesはSQLStoreにしか対応しておらず、SPARQLStoreでは動作しない。
https://github.com/SemanticMediaWiki/SemanticResultFormats/blob/6dd7e46c1913b6555d8ac2dd0ef8385d0e214709/formats/datatables/SearchPanes.php#L51