レベル: 中級 Uche Ogbuji (uche@ogbuji.net), Principal Consultant, Fourthought, Inc.
2002年 4月 02日 Uche Ogbujiは、これまで彼が述べた初歩的なAPIよりも格段に洗練されたRDF照会言語に話題を移します。これは、この後の記事で取り上げる問題追跡機能の記事を理解するための基礎になります。
これまでは、問題追跡機能のRDFメタデータを使用および照会する方法を簡単に説明するために、簡易かつ単純な照会APIを使用してきました。ここでは、より完全な照会言語に移ります。この言語によって、より明瞭なミドルウェア・コードを記述することができ、少し前の記事で例証したWordNetモデルのような、大規模なモデルを実現するために必要なパフォーマンスを得ることができます。
Versa: RDF照会言語
Versaは、オープンなRDF照会言語で、開発者が(他のアプリケーション内で使用することのできる)RDFツールについて求めている、一般的な要件に基づいて作られました。これは、単なるRDFという世界を超えた製品です。Versaは、RDFモデルを3つの要素の集合として捉えるのではなく、RDFモデルにおけるノードおよび弧 (arc)に注目します。そして、柔軟な照会を行なうためのコア・データ・モデルおよびきわめて豊富な関数およびプリミティブのセットを提供します。Versaは頻繁に関数を使用するため、使用感はLISPに似たところがあります。Versaはまた、他の多くのRDF照会システムにない、完全なブール論理および集合演算、推移的演算、集合体、サブストリングの突き合わせ、その他のコア・データ型操作などの機能を備えています。オリジナルのVersa仕様の作成には、私もかかわっています。
Versaの中心機能は、モデルのグラフに含まれるパターンを突き合わせるトラバース式です。次に示すのは、トラバース式の例です。
all() 関数は、モデル内のすべてのリソースの集合を戻します。従来のRDFモデル図に照らし合わせてみると、このことは、すべての長円形および弧を戻し、長方形は戻さないことを意味します。"-" トークンと "->" トークンは、トラバース演算子と呼ばれるものを形成します。この演算子は、各リソースから特定の弧をたどる必要があることを指示します。この例では、弧はrdf:type です。* は、このトラバースのすべてのエンドポイントが必要であることを表します。実際に、このトラバース式は、rdf:type 述部を含むすべてのステートメントのオブジェクトを戻します。
これを例証するために、前回の記事で扱ったサンプルRDF問題追跡機能の実例をリスト1に示しますので、それを見てみましょう。
<?xml version='1.0'?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY daml "http://www.daml.org/2001/03/daml+oil#">
<!ENTITY dc "http://purl.org/dc/elements/1.1/">
<!ENTITY foaf "http://xmlns.com/foaf/0.1/">
<!ENTITY it "http://rdfinference.org/schemata/issue-tracker/">
<!ENTITY rit "http://rdfinference.org/ril/issue-tracker/">
]>
<rdf:RDF
xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;"
xmlns:daml="&daml;"
xmlns:rit="&rit;"
xmlns:it="⁢"
xmlns:dc="&dc;"
xmlns:foaf="&foaf;"
xmlns="⁢"
>
<rdf:Description rdf:about='http://rdfinference.org/ril/ril-20010502'>
<issue rdf:resource='&rit;i2001030423'/>
<issue rdf:resource='&rit;i2001042003'/>
</rdf:Description>
<Issue rdf:about='&rit;i2001030423'>
<dc:title>Unnecessary abbreviation</dc:title>
<dc:creator rdf:resource='mailto:Alexandre.Fayolle@logilab.fr'/>
<dc:description>Is the abbreviation of rdf:type predicates needed?</dc:description>
<dc:date>2001-03-04</dc:date>
<comment rdf:parseType="Resource">
<dc:creator rdf:resource='mailto:Alexandre.Fayolle@logilab.fr'/>
<dc:description>The abbreviation in listing 8 doesn't seem needed.</dc:description>
</comment>
<action rdf:parseType="Resource">
<dc:description>Organize a vote on this topic</dc:description>
<it:assignee rdf:resource='mailto:uche.ogbuji@fourthought.com'/>
</action>
</Issue>
<Issue rdf:about='&rit;i2001042003'>
<dc:title>Inconsistent versioning</dc:title>
<dc:creator rdf:resource='mailto:Nicolas.Chauvat@logilab.fr'/>
<dc:description>RIL versioning is unclear (mix of 0.1, 0/1, 0.2 and 0/2)</dc:description>
<dc:date>2001-04-20</dc:date>
<action rdf:parseType="Resource">
<dc:description>Correct all to use the "0/1" form in the next draft.</dc:description>
<it:assignee rdf:resource='mailto:uche.ogbuji@fourthought.com'/>
</action>
</Issue>
<rdf:Description rdf:about='mailto:Alexandre.Fayolle@logilab.fr'>
<foaf:name>Alexandre Fayolle</foaf:name>
</rdf:Description>
<rdf:Description rdf:about='mailto:uche.ogbuji@fourthought.com'>
<foaf:name>Uche Ogbuji</foaf:name>
</rdf:Description>
<rdf:Description rdf:about='mailto:Nicolas.Chauvat@logilab.fr'>
<foaf:name>Nicolas Chauvat</foaf:name>
</rdf:Description>
</rdf:RDF>
|
図1は、これをグラフ形式で表したものです。
図1. RDF問題追跡機能サンプルのグラフ・モデル
このモデルでこの照会を実行すると、リソースのリストが得られます (これは、rdf:type ステートメントのオブジェクトがリソースであるためです)。リテラル・オブジェクトとリソース・オブジェクトを含む述部を使用した場合には、結果はリテラルとリソースのリストになります。4Suite (4Suiteの詳細については、以前の記事を参照してください) を使用してこれをテストするためには、リスト1をファイルissues.rdfにコピーし、以下に赤で強調表示されるコマンドをコマンド・ラインで実行してください。
$4versa --rdf-file=issues.rdf "all() - rdf:type -> *"
::: Using cDomlette
Executing Query:
all() - rdf:type -> *
With nsMapping of:
vtrav --> http://rdfinference.org/versa/0/2/traverse/
xml --> http://www.w3.org/XML/1998/namespace
vsort --> http://rdfinference.org/versa/0/2/sort/
rdfs --> http://www.w3.org/2000/01/rdf-schema#
rit --> http://rdfinference.org/schemata/issue-tracker/
it --> http://rdfinference.org/schemata/issue-tracker/
rdf --> http://www.w3.org/1999/02/22-rdf-syntax-ns#
foaf --> http://xmlns.com/foaf/0.1/
versa --> http://rdfinference.org/versa/0/2/
None --> http://rdfinference.org/schemata/issue-tracker/
daml --> http://www.daml.org/2001/03/daml+oil#
<List>
<Resource>http://rdfinference.org/schemata/issue-tracker/Issue/<Resource>
<Resource>http://rdfinference.org/schemata/issue-tracker/Issue</Resource>
</List>
|
これによって得られるリソースのリスト (単純なXML形式で表示されます) は太字で示されます。このコマンドによるその他の出力は、説明のためのものです。この出力は、実行中のVersa照会をエコーしたもので、エンジンによって認識されるネームスペース宣言を表しています。4versaは、ユーザーの便宜のために、ソース・ファイルのルート・エレメントに含まれているすべてのネームスペース宣言を自動的に捕そくします。
トラバース早分かり
一般に、トラバース式の形式は次のようになっています。
list-expression -list-expression ->boolean-expression
|
リスト式は、リソースのリスト、またはリソースのリストに変換することのできる結果を戻す任意の式です。したがって、単一のリソース (rdf:type) を戻す式は、単一項目のリスト・タイプに変換されます。RDF URIがrdf:type などの形式、および修飾名またはQNames と呼ばれる形式に省略されることは、すでに示したとおりです。これらは、最初の部分をURIベースに拡張し (例えば、rdf はhttp://www.w3.org/1999/02/22-rdf-syntax-ns# になります)、その後で2番目の部分に連結することにより、完全なURIに変換されます。これにより、rdf:type がhttp://www.w3.org/1999/02/22-rdf-syntax-ns#type になります。Versaでは、URIを詳細に書くこともできます。つまり、@"http://www.w3.org/1999/02/22-rdf-syntax-ns#type" と書くこともできます。例えば、次のようになります。
all() - @"http://www.w3.org/1999/02/22-rdf-syntax-ns#type" -> *
|
トラバース式の3番目の部分はブール式です。* を使用してすべてのオブジェクトを選択する方法についてはすでに述べました。また、結果を限定して選択することもできます。例えば、モデル内のリソースのすべての日付プロパティーを得るには、次の式を使用することができます。
これによって得られる結果は、次のとおりです。
<List>
<String>2001-03-04</String>
<String>2001-04-20</String>
</List>
|
特定の日付を選択するには、次のように書くことができます。
all() - dc:date -> eq("2001-04-20")
|
eq 関数は引数をコンテキストと比較し、両者が同じである場合にはtrueを戻します。Versaにおけるコンテキストの考え方は、XPathの場合に似ていますが、より単純です。Versaでは、コンテキストとは、式を評価するときに考慮される単一の値のことです。ドット記号を使用すると、コンテキストに直接アクセスすることができます。eq 関数を使用して2つの引数を明示的に比較することもできるため、上の式は次のように書くこともできます。
all() - dc:date -> eq(., "2001-04-20")
|
トラバース式の3番目の部分では、コンテキストは、最初と2番目の部分から得られる部分的な結果の1つです。例えば上の例で、各オブジェクトは "2001-04-20" と比較されます。最終結果は、比較の結果がtrueになったオブジェクトのリストであり、この場合には次のようになります。
<List>
<String>2001-04-20</String>
</List>
|
図2は、トラバース式の機能の一部を示しています。
図2. トラバース式の機能の説明
この一見明白な照会は、特定の値がモデルであるのかどうかを判断するのに役立ちます。例えば、上の例の "2001-04-20" を "2002-03-15" に置き換えると、結果は空のリストになります。もちろん、トラバース式は、さらに複雑な用途に使用することができます。例えば、リソースの日付のうち3月中の日付をすべて検索するには、次のようにします。
all() - dc:date -> contains("-03-") |
これによって、次の結果が得られます。
<List>
<String>2001-03-04</String>
</List>
|
逆方向トラバース
特定の日付のリソース を得られるようにすると、さらに便利になるでしょう。これを行うには、dc:date 弧に対する日付から対象リソースへと向かう逆方向の作業を行なう必要があります。Versaは、この操作を逆方向トラバースという形式で提供します。次に例を示します。
"2001-03-04" <- dc:date - *
|
これにより、日付が "2001-03-04" になっているすべてのリソースが戻されます。
<List>
<Resource>http://rdfinference.org/ril/issue-tracker/i2001030423</Resource>
</List>
|
逆方向トラバースの形式は、次のとおりです。
list-expression <-list-expression -boolean-expression
|
これは、順方向トラバースとまったく同じように機能します。どちらのタイプのトラバースもチェーンにすることができるため、日付が "2001-03-04" になっているすべてのリソースのタイトルを調べることもできます。
("2001-03-04" <- dc:date - *) - dc:title -> *
|
これによって、次の結果が得られます。
<List>
<String>Unnecessary abbreviation</String>
</List>
|
富の分配
ここまでは、すべての照会は単一の値を戻していました。複数の値を一度に戻す必要がある場合も多いでしょう。Versaは、トラバース式の結果を基にして行なわれるリスト操作によって、これを行ないます。リストを扱うためによく使用される関数として、distribute があります。これは、リスト内の各項目に1つまたは複数の式を適用するものです。結果はリストのリストになります。Versaでは、list(rit:i2001030423, rit:i2001042003) のような式 (これは、2つのリソースのリストです) を使用して、リストを直接表現することができます。次の式では、これらの各リソースのタイトルと日付が得られます。
distribute(list(rit:i2001030423, rit:i2001042003), ".-dc:title->*", ".-dc:date->*")
|
これにより、リストのリストが得られます。
<List>
<List>
<List>
<String>Unnecessary abbreviation</String>
</List>
<List>
<String>2001-03-04</String>
</List>
</List>
<List>
<List>
<String>Inconsistent versioning</String>
</List>
<List>
<String>2001-04-20</String>
</List>
</List>
</List>
|
distribute 関数の最初の引数はリストです。リスト内の各項目が順番に使用されます。2番目以降の引数はストリングであり、これらは副照会として扱われます。これらは、コンテキストの現行リスト項目を使用して動的に評価されます (コンテキストは、前に述べたように、ドットを使用して参照されます)。図3は、この照会の働きを示しています。
図3. 分配の機能の説明
この技法を、トラバース式の結果 (リスト) に対して使用することができます。最後の例として、Versaで特別なショートカット機能を使用する方法を説明します。type 関数は、(rdf:type 述部について説明したように) 指定したRDFタイプのすべてのリソースを検索します。問題を送ったすべての人のIDおよび名前を得るためには、次のように書くことができます。
distribute(type(it:Issue)-dc:creator->*, ".", ".-foaf:name->*")
|
副次式の中では、コンテキストを別の式の一部とすることなく、直接使用できることに注意してください。結果は次のようになります。
<List>
<List>
<Resource>mailto:Nicolas.Chauvat@logilab.fr</Resource>
<List>
<String>Nicolas Chauvat</String>
</List>
</List>
<List>
<Resource>mailto:Alexandre.Fayolle@logilab.fr</Resource>
<List>
<String>Alexandre Fayolle</String>
</List>
</List>
</List>
|
ここで、1つ注意しなければならないことがあります。.-foaf:name->* 副次式から得られるストリングはリストに入りますが、. 副次式から得られるリソースはリストに入りません。これは、トラバース演算子が、結果の中に項目が1しかなくても、まったくなくても、常にリストを戻すからです。私たちのモデルでは、それぞれの人のリソースには1つの名前しかないことが分かっていますので、通常は、いずれにしても最下位のリストを無視します。Versaはデータ変換関数を備えています。そのうちの1つは、引数をストリングに変換するstring 関数です。リストの変換は、その最初 (または唯一) の項目のストリング値を獲得することによって行なわれます。したがって、次のように書くと、
distribute(type(it:Issue)-dc:creator->*, ".", "string(.-foaf:name->*)")
|
トラバース副次式で余分なリストが除去され、次の結果が得られます。
<List>
<List>
<Resource>mailto:Nicolas.Chauvat@logilab.fr</Resource>
<String>Nicolas Chauvat</String>
</List>
<List>
<Resource>mailto:Alexandre.Fayolle@logilab.fr</Resource>
<String>Alexandre Fayolle</String>
</List>
</List>
|
結論
今回の記事では、Versaの基本的な事項を説明しました。これをお読みになった読者は、すぐにVersaを利用することができます。Versaにはほかにも多くの機能がありますが、そのほとんどは、特殊化された関数の形で提供されており、これらを使用すれば、すぐに使いこなせるようになるでしょう。Versaに関するその他の参考文献を「参考文献」セクションにリストしておきました。次回の記事では、これまでこのシリーズで述べたすべての照会ニーズを、Versaで処理するための方法について説明する予定です。
参考文献
著者について  | 
|  | Uche Ogbuji は、次世代の Web 技術を専門とするサービスの会社である、Uli, LLC の代表者です。Ogbuji 氏は XML、RDF、およびナレッジ管理アプリケーション用のオープン・ソース・プラットフォームである 4Suite の開発リーダーであり、Versa RDF 照会言語の開発リーダーでもあります。ナイジェリア出身のコンピューター・エンジニア兼ライターで、米国コロラド州ボールダー在住です。彼に関して詳しくは、彼のブログである Copia を見てください。 |
記事の評価
|