LoginSignup
13
13

More than 5 years have passed since last update.

Wikidata Query Service に SPARQL 問合せをしてみた

Last updated at Posted at 2015-12-21

SPARQL Advent Calendar 2015、21日の記事です。1日くらい送れてしまいましたが...

Wikidata Query Service (Beta) に SPARQL 問合せを行ってみました。

Wikidata とは

Wikidata は、Wikimedia のプロジェクトの1つで、コミュニティによるデータの Wikipedia と言ったところでしょうか。データは三つ組で記述され、Linked Dataとして、他のサービスのURIにリンクさせることができます。最近SPARQLエンドポイントが公開されたそうです。

DBpedia が Wikipedia から機械的に抽出され作られたRDFデータであるのに対し、
Wikidata はコミュニティによって記述されたLinke Dataであるところが異なると認識しています。
(おかしな解釈だったらコメント下さい :bow:

Wikidata Query Service に SPARQL エンドポイントが公開されています。
画面右上にある「Examples」から、数多くのサンプルを試すことができました。

スクリーンショット 2015-12-22 午前2.39.21.png

SPARQL

Examples などを参考に、今回書いてみたクエリが以下です。

PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>

select ?movie ?jalabel ?enlabel
where {
    ?movie p:P57 ?directorStatement . # director
    ?directorStatement ps:P57 wd:Q38222 .

    ?movie p:P179 ?seriesStatement . # series
    ?seriesStatement ps:P179 wd:Q462 .

    ?movie rdfs:label ?jalabel filter (lang(?jalabel) = "ja") .
    ?movie rdfs:label ?enlabel filter (lang(?enlabel) = "en") .
}

このクエリは、映画のID、日本語でのラベル、および英語でのラベルを得ます。映画の条件は

  • series が Star Wars である
  • director が George Lucas である

ような映画です。
つまり、「George Lucas が監督の、Star Wars シリーズの映画ID、日本語タイトル、および英語タイトル」を得るクエリです。

クエリ中の Predicate, Object はそれぞれ以下に対応しています。URIを見てだいたいどんなリソースかとわかると嬉しいですが、連番だと厳しいですね。

以下が結果です。

?movie ?jalabel ?enlabel
wd:Q181069 スター・ウォーズ エピソード2/クローンの攻撃 Star Wars Episode II: Attack of the Clones
wd:Q165713 スター・ウォーズ エピソード1/ファントム・メナス Star Wars Episode I: The Phantom Menace
wd:Q17738 スター・ウォーズ エピソード4/新たなる希望 Star Wars Episode IV: A New Hope
wd:Q42051 スター・ウォーズ エピソード3/シスの復讐 Star Wars Episode III: Revenge of the Sith

細かいところだと直接 ?movie p:P57 wd:Q38222 . と書きたいところですが、
property statement (ps:) を経由しないとダメなようです。
そのため、?directorStatement, ?seriesStatement を経由して関係を記述しています。
(なぜこのような構造になっているか、どなたか教えていただけないでしょうか)

ちなみに、George Lucas でない監督の作品名と、その監督名は以下のクエリで得られます。

PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>

select ?movie ?jalabel ?enlabel ?directorName
where {
    ?movie p:P57 ?directorStatement . # director
    minus { ?directorStatement ps:P57 wd:Q38222 . } # not George Lucas
    ?directorStatement ps:P57 ?director .
    ?director rdfs:label ?directorName filter (lang(?directorName) = "en") .

    ?movie p:P179 ?seriesStatement . # series
    ?seriesStatement ps:P179 wd:Q462 .

    ?movie rdfs:label ?jalabel filter (lang(?jalabel) = "ja") .
    ?movie rdfs:label ?enlabel filter (lang(?enlabel) = "en") .
}

minus は SPARQL 1.1 から入った機能のようです。この結果は以下になります。

?movie ?jalabel ?enlabel ?directorName
wd:Q181803 スター・ウォーズ エピソード6/ジェダイの帰還 Star Wars Episode VI: Return of the Jedi Richard Marquand
wd:Q6074 スター・ウォーズ エピソード7 Star Wars: The Force Awakens J. J. Abrams
wd:Q181795 スター・ウォーズ エピソード5/帝国の逆襲 The Empire Strikes Back Irvin Kershner

エピソード7の邦題「フォースの覚醒」がついてないので、Wikipediaのように編集してみようと思います(-> 簡単に直せました)。

まとめというか感想

大学・大学院でLinked Data(RDF)の研究をしていたので、SPARQLを書くのは初めてではありませんでしたが、
卒業以来ほぼ2年ぶりくらいに書いたので、だいぶ時間がかかってしまいました。

Wikidata のエンドポイントは一般的な Virtuoso の SPARQL エンドポイントよりも使いやすかったです。

Wikidata は DBpedia と違って?(機械的に抽出していないという意味で)人がメンテナンスしているデータのように見えるので、
無駄に Predicate がたくさんくっついてるというような印象はありませんでした。

参考

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13