5.3 SPARQLを使う
SPARQL(SPARQL protocol and RDF query language)はRDFグラフにおける検索のための、問い合わせ言語である。RDBのSQL(structured query language)の位置づけだろう。
RDFlibはSPARQLのエンジンを含むので、owlready2はSPARQLを利用できる。
5.3.1 SPARQLを用いた検索
graph.query([SPARQLクエリ])メソッドを利用する。graphはRDBlibのグラフオブジェクトである。帰り値(オブジェクト)は、RDFlibのフォーマットによるエンティティ(のタプル)をまとめたオブジェクトSPARQLResultとなる。例を示す。
>>> from owlready2 import *
>>> onto = get_ontology('bacteria.owl').load()
>>> from rdflib import *
>>> graph = default_world.as_rdflib_graph()
>>> graph.query("""
... SELECT ?b WHERE {
... ?b
... <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
... <http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#Bacterium>.
... }""" )
<rdflib.plugins.sparql.processor.SPARQLResult object at 0x0000020EED0B6350>
>>> list(graph.query("""
... SELECT ?b WHERE {
... ?b
... <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
... <http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#Bacterium>.
... }""" ))
[(rdflib.term.URIRef('http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#unknown_bacterium'),)]
>>> list(graph.query("""
... SELECT ?b ?c WHERE {
... ?b
... <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
... ?c .
... }""" ))
[(rdflib.term.URIRef('http://anonymous'), rdflib.term.URIRef('http://www.w3.org/2002/07/owl#Ontology')),
(rdflib.term.URIRef('http://lesfleursdunormal.fr/static/_downloads/bacteria.owl'), rdflib.term.URIRef('http://www.w3.org/2002/07/owl#Ontology')),
~~~
(rdflib.term.URIRef('http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#unknown_bacterium'), rdflib.term.URIRef('http://www.w3.org/2002/07/owl#NamedIndividual')),
(rdflib.term.BNode('43'), rdflib.term.URIRef('http://www.w3.org/2002/07/owl#AllDisjointClasses')), (rdflib.term.BNode('47'), rdflib.term.URIRef('http://www.w3.org/2002/07/owl#AllDisjointClasses'))]
SPARQLの基礎的な構文は次のようになる。
| SELECT ?s ?p ?o WHERE { ?s ?p ?o } |
|---|
であり、値による絞り込みの句、結果の集合を操作したりグループ化する句を付加するものである。SPARQLの問い合わせ文の中では、RDFlibのエンティティのowlready2のための表現(URIRefなど)は不要である。但し、エンティティは括弧(< >)でくくる。これはSPARQLとしてそのように定められている。
graph.query_owlready([SPARQLクエリ])では、結果はowlready2の書式(オブジェクトのリスト)が返り値である。
>>> list(graph.query_owlready("""
... SELECT ?b WHERE {
... ?b
... <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
... <http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#Bacterium>.
... }""" ))
...
[[bacteria.unknown_bacterium]]
SPARQLでは複数のRDFトリプルの関係を利用して検索できる。以下の例では関係付けのために?rという変数を利用するが、返すのはSELECTの対象となっている?bのエンティティのみである。
>>> list(graph.query_owlready("""
... SELECT ?b WHERE {
... ?b
... <http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#has_grouping>
... ?r .
...
... ?r
... <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
... <http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#InCluster> .
... }""" ))
...
[[bacteria.unknown_bacterium]]
なお、?rとして当てはまるインディビデュアルはbacteria.in_cluster1だけである。
問い合わせの方法としては、もう一つ、default_world.sparql_query()メソッドがある。これはgraph.query_owlready()と同様の返り値を得るが、graphオブジェクトをわざわざ取らなくてもよい。
SPARQLクエリの文字列は、Pythonの文字列のように句(文字列型)の代入を扱うことができる。フォーマットで埋め込む記号%sは角括弧(< >)でくくり、また変数の値はIRIとなる。
>>> c = onto.Bacterium
>>> list(graph.query("""
... SELECT ?b WHERE {
... ?b
... <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
... <%s>
... }""" % c.iri ))
...
[(rdflib.term.URIRef('http://lesfleursdunormal.fr/static/_downloads/bacteria.owl#unknown_bacterium'),)]
なお、これまでの例ではインディビデュアルしか検索していないが、クラスも検索できる。
>>> individual = onto.unknown_bacterium
... list(default_world.sparql_query("""
... SELECT ?class WHERE {
... <%s> a ?class .
... ?class a <http://www.w3.org/2002/07/owl#Class> .
... }""" % individual.iri))
...
[[bacteria.Bacterium]]