正規表現によるデータの照合
若干効率が低下しますが、SPARQLクエリでは正規表現による照合を行うことができます。このテクニックの一例として、リスト6ではRDFファイル「rdf_files/oil_example.n3」を使用しています。リスト6のSPARQLクエリは、目的語フィールドに単語『oil』を含み、かつ述語フィールドがkb:containsIndustryTerm
と一致するすべてのRDFトリプルを探そうとします。正規表現による照合を行うため、前述のJRubyサンプルプログラムの1つを使い(リスト2を参照)、読み込むN3ファイルの名前とSPARQLクエリの文字列を次のように変更します。
tsm.loadRDF("rdf_files/oil_example.n3") sparql_query = "PREFIX kb: SELECT ?subject ?object WHERE { ?subject kb:containsIndustryTerm ?object FILTER regex(?object, \"oil\") . }"
ここでは、?object
の後ろに?object
の値を『oil』を含む文字列に制限するフィルタ項を追加しました。マッチするRDFトリプルが2つあるので、次の2行(それぞれ記事のURLと目的語の値を持つ)が出力されます。
[http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16/, oil] [http://news.yahoo.com/s/nm/20080616/ts_nm/usa_politics_dc_2/, oil prices]
さて、これと同様の、しかしもう少し面白い例を考えてみましょう。この正規表現の例を、マッチした記事について、すべてのトリプルを探すように拡張します。前の例で見つかった記事のURLが与えられたとするなら、SPARQLクエリの文字列を次のように変更することで、マッチした記事のURLのいずれかと一致する主語を持つすべてのRDFトリプルをひとまとめにできます。
sparql_query = "PREFIX kb: SELECT ?subject ?predicate ?object2 WHERE { ?subject kb:containsIndustryTerm ?object FILTER regex(?object, \"oil\") . ?subject ?predicate ?object2 . }"
このクエリには2つのWHERE句があります。最初の句はkb:containsIndustryTerm
と一致する述語項を持つすべてのトリプルとマッチし、次の句は主語が最初のWHERE句とマッチするすべてのトリプルとマッチします。結果として、それぞれ主語/述語/目的語の3つ値が含まれることになります。
@prefix kb: <http://knowledgebooks.com/ontology#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . kb:containsCity rdfs:subPropertyOf kb:containsPlace . kb:containsCountry rdfs:subPropertyOf kb:containsPlace . kb:containsState rdfs:subPropertyOf kb:containsPlace . <http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16/> kb:containsCity "Burlington" , "Denver" , "St. Paul" , "Chicago" , "Quincy" , "CHICAGO" , "Iowa City" ; kb:containsRegion "U.S. Midwest" , "Midwest" ; kb:containsCountry "United States" , "Japan" ; kb:containsState "Minnesota" , "Illinois" , "Mississippi" , "Iowa" ; kb:containsOrganization "National Guard" , "U.S. Department of Agriculture" , "White House" , "Chicago Board of Trade" , "Department of Transportation" ; kb:containsPerson "Dena Gray-Fisher" , "Donald Miller" , "Glenn Hollander" , "Rich Feltes" , "George W. Bush" ; kb:containsIndustryTerm "food inflation" , "food" , "finance ministers" , "oil" . <http://news.yahoo.com/s/nm/20080616/ts_nm/usa_politics_dc_2/> kb:containsCity "Washington" , "FLINT" , "Baghdad" , "Arlington" , "Flint" ; kb:containsCountry "United States" , "Afghanistan" , "Iraq" ; kb:containsState "Illinois" , "Virginia" , "Arizona" , "Michigan" ; kb:containsOrganization "White House" , "Obama administration" , "Iraqi government" ; kb:containsPerson "David Petraeus" , "John McCain" , "Hoshiyar Zebari" , "Barack Obama" , "George W. Bush" , "Carly Fiorina" ; kb:containsIndustryTerm "oil prices" . kb:containsCity "WASHINGTON" ; kb:containsCountry "United States" ; kb:containsState "Maryland" ; kb:containsIndustryTerm "video games" .
RDFスキーマの異なる異種ソースからのデータのマージ
セマンティックWebアプリケーションで異種ソースのデータを扱うことになるのは必定で、その機能をどう実装すればよいかを次の例で示します。ここでは、前の例のファイル「rdf_files/news.n3」に加え、スキーマが大幅に異なる「rdf_files/news_2.n3」も使用します。
@prefix ex: <http://example.com/ontology#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . <http://news.yahoo.com/s/made_up_data/made_up_article_1/> kb:about "Academy Award red carpet got wet in the rain" ; ex:author "Joy Smith" ; ex:location "United States" , "Los Angeles" ; kb:keyword "entertainment" , "movies" . <http://news.yahoo.com/s/made_up_data/made_up_article_2/> kb:about "Oil prices rise" ; ex:author "Sam Suvy" ; ex:location "United States" , "Chicago" ; kb:keyword "cars" , "fuel", "oil" .
この新しいRDFファイルを前の例のRDFファイル「news.n3」と比べると、次の類似点があります。
- 「news_2.n3」ファイルのプロパティ
location
は、「news.n3」におけるcontainsCity
、containsCountry
、containsState
の各プロパティと類似しています。これらのプロパティは定義されている名前空間が同じでありませんが、そのことは問題になりません(後述)。 - 「news_2.n3」ファイルのプロパティ
keyword
は、「news.n3」におけるプロパティcontainsIndustryTerm
と類似しています。keyword
とcontainsIndustryTerm
を目的語の値として曖昧に照合するのは、当然と言えば当然です。
場所をどう扱うかという問題は、もう1つのプロパティステートメントを追加するだけで解決できます。
ex:location rdfs:subPropertyOf kb:containsPlace .
こうすれば、kb:containsPlace
に対してどんなSPARQLクエリを実行するときもデータの修正は不要になります。両方の情報ソースの2番目の類似点についてキーワード(業界の標準用語)のリストを得る場合は、次のように別のステートメントを追加します。
ex:keyword rdfs:subPropertyOf kb:containsIndustryTerm .
私としてはSPARQLクエリにおいてむしろ自分独自の名前空間であるknowledgebooks.comを使いたいところですが、ex:keyword
プロパティを使うのであれば、このRDFステートメントの主語と目的語の順番を逆にするだけで済みます。