LODクラウド検索のクエリ言語「SPARQL」を実際に実行してみます。
この記事はオープンデータ カテゴリーの記事一覧 - littlewingの第五回です。
SPARQLで何ができるのか?
- SPARQL言語を使うことで、LODクラウド上のデータを自由に取得・加工することができます。
- LODクラウドデータベース用のSQL言語のようなものです。
- 各LODにはSPARQLエンドポイントが存在しており(無い場合もあります)、そこに対してSPARQLを実行することで実行結果を取得できます。
- 実行結果はXML,JSON,HTMLtableなど加工しやすいフォーマットで取得できます。
ひとまず、SPARQLのサンプルクエリを淡々と紹介
ja.dbpedia.orgのエンドポイントであるVirtuoso SPARQL Query Editorに以下のSPARQLを流し込むことで動作が確認できます。
任意の3つの組を取得する基本構文
select ?s ?p ?o where{?s ?p ?o.} LIMIT 100
- whereは省略可能(結果は上と一緒です)
select ?s ?p ?o {?s ?p ?o.} LIMIT 100
主語(subject)と目的語(object)を述語(predicate)を指定するので多くのサンプルでは?s ?p ?oと書かれることが多いです。
- 変数名は自分で決めることができます。
select ?aaa ?bbb ?ccc {?aaa ?bbb ?ccc.} LIMIT 100
- 「*」で出力内容を個別に指定せずにすべて表示することができます。(SQLと一緒ですね)
select * {?aaa ?bbb ?ccc.} LIMIT 100
- dbpediaから東京都のデータを取得(主語を固定して、述語、目的語を変数として取得)
select distinct * where { <http://ja.dbpedia.org/resource/東京都> ?p ?o . }
distinct で重複する結果をまとめています。
- prefixで記述を簡素化
PREFIX dbpedia:<http://ja.dbpedia.org/resource/> select distinct * where { dbpedia:東京都 ?p ?o . }LIMIT 100
- 東京都のリーダーの情報を取得(目的語のみが変数になっています。)
PREFIX dbpedia: <http://ja.dbpedia.org/resource/> PREFIX dbp-owl: <http://dbpedia.org/ontology/> #jpではないことに注意!! SELECT ?leaderName WHERE { dbpedia:東京都 dbp-owl:leaderName ?leaderName . }
- 東京都に隣接する都道府県の情報を取得
SELECT DISTINCT ?rinsetsu_label WHERE { ?tokyo_uri prop-ja:隣接都道府県 ?rinsetsu_uri . ?tokyo_uri rdfs:label ?tokyo_label. FILTER regex(?tokyo_uri , "東京都") ?rinsetsu_uri rdfs:label ?rinsetsu_label. }
*「都道府県とその隣接都道府県数」を検索するためのクエリです。 * 6行目で都道府県名(?todoufuken_label)でグルーピングを行い、2行目で隣接都道府県(?rinsetsu_uri)の数を変数「name_rinsetsu」で参照しています。
SELECT DISTINCT ?todoufuken_label count(?rinsetsu_uri) As ?num_rinsetsu WHERE { ?todoufuken_uri prop-ja:隣接都道府県 ?rinsetsu_uri. ?todoufuken_uri rdfs:label ?todoufuken_label. } GROUP BY (?todoufuken_label)
漫画家と受賞作品
- 漫画家一覧
PREFIX dbp:<http://ja.dbpedia.org/resource/> PREFIX dbp-owl: <http://dbpedia.org/ontology/> PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#> SELECT * WHERE{ ?creator rdf:type dbp-owl:ComicsCreator. }
- そのうち手塚治虫文化賞受賞者一覧
PREFIX dbp:<http://ja.dbpedia.org/resource/> PREFIX dbp-owl: <http://dbpedia.org/ontology/> PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#> SELECT * WHERE{ ?creator rdf:type dbp-owl:ComicsCreator; dbp-owl:award dbp:手塚治虫文化賞 . }
- そのうち、長野県出身
PREFIX dbp:<http://ja.dbpedia.org/resource/> PREFIX dbp-owl: <http://dbpedia.org/ontology/> PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#> SELECT * WHERE{ ?creator rdf:type dbp-owl:ComicsCreator; dbp-owl:award dbp:手塚治虫文化賞; dbp-owl:birthPlace dbp:長野県. }
- 受賞者と代表作品一覧
PREFIX dbp: <http://ja.dbpedia.org/resource/> PREFIX dbp-owl: <http://dbpedia.org/ontology/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?creatorName ?comics { ?creator a dbp-owl:ComicsCreator; dbp-owl:award dbp:手塚治虫文化賞; dbp-owl:notableWork ?comic; rdfs:label ?creatorName. ?comic rdfs:label ?comics . }
日本の携帯電話のリストを取得する
- キャリアがドコモの端末一覧
PREFIX dbp: <http://ja.dbpedia.org/resource/> PREFIX dbp-owl: <http://dbpedia.org/ontology/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT * { ?s prop-ja:キャリア "NTTドコモ"@ja. } LIMIT 100
- 発売日降順で並べるメーカー名も表示
SELECT DISTINCT * { ?s prop-ja:キャリア "NTTドコモ"@ja; prop-ja:製造 ?maker; prop-ja:発売年 ?releaseYear. } ORDER BY ASC(?releaseYear) LIMIT 100
よくわからないと思うので解説
SPARQLはSQLのようで、非なるもの
LODでは、RDF(Resource Description Framework)グラフと呼ばれる、主語(subject)と目的語(object)を述語(predicate)でリンクしたトリプル(triple)で表現します。
WHERE 部分の組み立てに注意
- WHERE 部分基本的に <主語><述語><目的語>.(ドット)がセットです。自分が何を操作しているのかをつねに意識してください。
;を使うと主語が省略できる
目的語の後は必ず.を書く
rdf:type は a と略すことができる。(必ず小文字のa)
夏目漱石の代表作と発表年を表示するSPARQL
考え方
主語 | 述語 | 目的語 |
---|---|---|
夏目漱石 | -> 代表作 | -> 変数として代表作を取得(複数) |
代表作 | -> 発売年 | -> 変数として年を取得 |
- 夏目漱石の代表作と発売年を表示
1: PREFIX dbp: <http://ja.dbpedia.org/resource/> 2: PREFIX dbp-owl: <http://dbpedia.org/ontology/> 3: PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 4: SELECT DISTINCT ?name ?sakuhinmei ?jidai 5: { 6: dbp:夏目漱石 rdfs:label ?name; 7: dbpedia-owl:notableWork ?sakuhin. 8: ?sakuhin rdfs:label ?sakuhinmei. 9: ?sakuhin dcterms:subject ?x. 10: FILTER regex(?x, "年の小説") . 11: ?x rdfs:label ?jidai. 12: } 13: ORDER BY ASC (?jidai) 14: LIMIT 100
1-3行目 :読みやすくするためにPREFIX を設定しています。これでdbp/dbp-owl/rdfsがつかえるようになります。
4行目 出力対象の変数を?name ?sakuhinmei ?jidaiの3つに絞り、かつ重複を除去(distinct)しています。 わからない人は[SELECT *]に入れ替えて結果を比べて見るといいでしょう。
6行目 http://ja.dbpedia.org/resource/%E5%A4%8F%E7%9B%AE%E6%BC%B1%E7%9F%B3(=主語) の rdfs:label(=述語)を変数(?name)(=目的語)として取得しています。PREFIX のdbpを使うことで簡潔に表現。
7行目 6行目で「;」を使うことで主語が省略されていますが、主語はdbp:夏目漱石です。夏目漱石(=主語)の代表作のデータラベル(dbpedia-owl:notableWork)(=述語) を変数名?sakuhinとして取得しています。これによって代表作の一覧が取得できます。
8行目 7行目で取得した代表作の変数?sakuhin を主語として、rdfs:label(=述語)を 変数名?sakuhinmei(=目的語)として取得しています。
9行目 変数?sakuhin のdcterms:subject(=述語)の内容を目的語の変数?xとして取得しています。
10行目 ?x に対して、「年の小説」という文字が含まれるdcterms:subjectのみにフィルターをかけています。
11行目 変数?xを主語として、rdfs:label(=述語)の値をx?jidaiとして取得しています。
13行目 並び順を?jidaiの昇順に並べ替えています。
- 14行目 取得件数を最大100件で制限をかけています。
取得結果
参考資料
- 一番わかりやすかったのは、このサイトでした。
- SPARQLの解説資料
活用方法