【注意】 このドキュメントは、W3CのSPARQL 1.1 Query Language W3C Recommendation 21 March 2013の和訳です。
このドキュメントの正式版はW3Cのサイト上にある英語版であり、このドキュメントには翻訳に起因する誤りがありえます。誤訳、誤植などのご指摘は、訳者までお願い致します。
First Update: 2013年7月21日
このドキュメントに対する正誤表を参照してください。いくつかの規範的な修正が含まれているかもしれません。
翻訳版も参照してください。
Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
RDFは、ウェブ上で情報を表すための、有向性の、ラベル付けされたグラフ・データ形式です。この仕様では、RDFに対するSPARQLクエリ言語の構文とセマンティクスを定義しています。SPARQLは、データがRDFそのものとして保存されているか、ミドルウェアを通してRDFとして見えるのかにかかわらず、さまざまなデータ情報源にまたがるクエリを表すために使用できます。SPARQLには、必須および任意のグラフ・パターンをその論理積と論理和とともに問い合わせる性能が含まれています。SPARQLは、ソースRDFグラフによる集約、サブクエリ、否定、式による値の作成、拡張可能な値テストやクエリの制約もサポートします。SPARQLクエリの結果は、結果集合またはRDFグラフでありえます。
この項は、このドキュメントの公開時のステータスについて記述しています。他のドキュメントがこのドキュメントに取って代わることがありえます。現行のW3Cの刊行物およびこの技術報告の最新の改訂版のリストは、http://www.w3.org/TR/のW3C技術報告インデックスにあります。
このドキュメントは、SPARQLワーキンググループが作成した以下の11のSPARQL 1.1勧告のうちの1つです。
旧バージョン以降、このドキュメントには実質的な変更はありませんでした。マイナーな編集上の変更がある場合には、変更履歴に詳細が記述されており、色分けした差分として見ることができます。
[email protected](公開アーカイブ)にコメントをお送りください。このドキュメントに対するSPARQLワーキンググループの作業は完了していますが、コメントは正誤表や今後の改定で扱われることがあります。公開討論は、[email protected](公開アーカイブ)で歓迎します。
このドキュメントは、W3Cメンバー、ソフトウェア開発者、他のW3Cグループ、および他の利害関係者によりレビューされ、W3C勧告として管理者の協賛を得ました。これは確定済みドキュメントであり、参考資料として用いたり、別のドキュメントで引用することができます。勧告の作成におけるW3Cの役割は、仕様に注意を引き付け、広範囲な開発を促進することです。これによってウェブの機能性および相互運用性が増強されます。
このドキュメントは、2004年2月5日のW3C特許方針の下で活動しているグループによって作成されました。W3Cは、このグループの成果物に関連するあらゆる特許の開示の公開リストを維持し、このページには特許の開示に関する指示も含まれています。不可欠な請求権(Essential Claim(s))を含んでいると思われる特許に関して実際に知っている人は、W3C特許方針の6項に従って情報を開示しなければなりません。
1 はじめに
1.1 ドキュメントの概要
1.2 キュメントの慣習
1.2.1 名前空間
1.2.2 データの記述
1.2.3 結果の記述
1.2.4 用語
2 シンプルなクエリの作成(参考情報)
2.1 シンプルなクエリの記述
2.2 複数マッチ
2.3 RDFリテラルのマッチング
2.3.1 リテラルと言語タグとのマッチング
2.3.2 リテラルと数値型とのマッチング
2.3.3 リテラルと任意のデータ型とのマッチング
2.4 クエリ結果の空白ノード・ラベル
2.5 式による値の作成
2.6 RDFグラフの構築
3 RDF用語制約(参考情報)
3.1 文字列の値の制限
3.2 数値の制限
3.3 その他の用語制約
4 SPARQL構文
4.1 RDF用語構文
4.1.1 IRIの構文
4.1.1.1 接頭辞名
4.1.1.2 相対IRI
4.1.2 リテラルの構文
4.1.3 クエリ変数の構文
4.1.4 空白ノードの構文
4.2 トリプル・パターンの構文
4.2.1 述語-目的語のリスト
4.2.2 目的語のリスト
4.2.3 RDFコレクション
4.2.4 rdf:type
5 グラフ・パターン
5.1 基本グラフ・パターン
5.1.1 空白ノード・ラベル
5.1.2 基本グラフ・パターン・マッチングの拡張
5.2 グループ・グラフ・パターン
5.2.1 空のグループ・パターン
5.2.2 フィルタの範囲
5.2.3 グループ・グラフ・パターンの例
6 オプション値の組み込み
6.1 オプションのパターン・マッチング
6.2 オプションのパターン・マッチングにおける制約
6.3 複数のオプションのグラフ・パターン
7 代替のマッチング
8 否定
8.1 グラフ・パターンを用いたフィルタリング
8.1.1 パターンの不在に関するテスト
8.1.2 パターンの存在に関するテスト
8.2 ソリューションの除外
8.3 NOT EXISTSとMINUSの関係と違い
8.3.1 例: 変数の共有
8.3.2 例: 固定パターン
8.3.3 例: 内部FILTER
9 プロパティー・パス
9.1 プロパティー・パス構文
9.2 例
9.3 プロパティー・パスと同等パターン
9.4 任意の長さのパス・マッチング
10 割り当て
10.1 BIND: 変数への割り当て
10.2 VALUES: インライン・データの提供
10.2.1 VALUES構文
10.2.2 VALUESの例
11 集約
11.1 集約の例
11.2 GROUP BY
11.3 HAVING
11.4 集約射影制限
11.5 集約の例(エラーがある場合)
12 サブクエリ
13 RDFデータセット
13.1 RDFデータセットの例
13.2 RDFデータセットの指定
13.2.1 デフォルト・グラフの指定
13.2.2 名前付きグラフの指定
13.2.3 FROMとFROM NAMEDの結合
13.3 データセットのクエリ実行
13.3.1 グラフ名へのアクセス
13.3.2 グラフIRIによる制限
13.3.3 ありうるグラフIRFの制限
13.3.4 名前付きグラフおよびデフォルト・グラフ
14 基本的な統合クエリ
15 ソリューション・シーケンスと修飾子
15.1 ORDER BY
15.2 射影
15.3 ソリューションの複製
15.4 OFFSET
15.5 LIMIT
16 クエリ形式
16.1 SELECT
16.1.1 射影
16.1.2 SELECT式
16.2 CONSTRUCT
16.2.1 空白ノードを持つテンプレート
16.2.2 RDFデータセットのグラフへのアクセス
16.2.3 ソリューション修飾子とCONSTRUCT
16.2.4 CONSTRUCT WHERE
16.3 ASK
16.4 DESCRIBE(参考情報)
16.4.1 明示的なIRI
16.4.2 資源の識別
16.4.3 資源の記述
17 式と値のテスト
17.1 オペランド・データ型
17.2 フィルタ評価
17.2.1 呼び出し
17.2.2 有効なブール値(EBV)
17.3 演算子マッピング
17.3.1 演算子の拡張性
17.4 関数の定義
17.4.1 関数の形式
17.4.1.1 バインド
17.4.1.2 IF
17.4.1.3 COALESCE
17.4.1.4 NOT EXISTSとEXISTS
17.4.1.5 logical-or
17.4.1.6 logical-and
17.4.1.7 RDFterm-equal
17.4.1.8 sameTerm
17.4.1.9 IN
17.4.1.10 NOT IN
17.4.2 RDF用語の関数
17.4.2.1 isIRI
17.4.2.2 isBlank
17.4.2.3 isLiteral
17.4.2.4 isNumeric
17.4.2.5 str
17.4.2.6 lang
17.4.2.7 datatype
17.4.2.8 IRI
17.4.2.9 BNODE
17.4.2.10 STRDT
17.4.2.11 STRLANG
17.4.2.12 UUID
17.4.2.13 STRUUID
17.4.3 文字列に関する関数
17.4.3.1 SPARQL関数の文字列
17.4.3.1.1 文字列の引数
17.4.3.1.2 引数の互換性の規則
17.4.3.1.3 文字列リテラルの返答の型
17.4.3.2 STRLEN
17.4.3.3 SUBSTR
17.4.3.4 UCASE
17.4.3.5 LCASE
17.4.3.6 STRSTARTS
17.4.3.7 STRENDS
17.4.3.8 CONTAINS
17.4.3.9 STRBEFORE
17.4.3.10 STRAFTER
17.4.3.11 ENCODE_FOR_URI
17.4.3.12 CONCAT
17.4.3.13 langMatches
17.4.3.14 REGEX
17.4.3.15 REPLACE
17.4.4 数値の関数
17.4.4.1 abs
17.4.4.2 round
17.4.4.3 ceil
17.4.4.4 floor
17.4.4.5 RAND
17.4.5 日時の関数
17.4.5.1 now
17.4.5.2 year
17.4.5.3 month
17.4.5.4 day
17.4.5.5 hours
17.4.5.6 minutes
17.4.5.7 seconds
17.4.5.8 timezone
17.4.5.9 tz
17.4.6 ハッシュ関数
17.4.6.1 MD5
17.4.6.2 SHA1
17.4.6.3 SHA256
17.4.6.4 SHA384
17.4.6.5 SHA512
17.5 XPathコンストラクタ関数
17.6 拡張可能な値テスト
18 SPARQLの定義
18.1 初期定義
18.1.1 RDF用語
18.1.2 Simple Literal
18.1.3 RDFデータセット
18.1.4 クエリ変数
18.1.5 トリプル・パターン
18.1.6 基本グラフ・パターン
18.1.7 プロパティー・パス・パターン
18.1.8 ソリューション・マッピング
18.1.9 ソリューション・シーケンス修飾子
18.1.10 SPARQLクエリ
18.2 SPARQL代数への置換
18.2.1 変数の範囲
18.2.2 グラフ・パターンの変換
18.2.2.1 構文形式の展開
18.2.2.2 FILTER要素の集約
18.2.2.3 プロパティー・パス式の置換
18.2.2.4 プロパティー・パス・パターンの置換
18.2.2.5 基本グラフ・パターンの置換
18.2.2.6 グラフ・パターンの置換
18.2.2.7 グループのフィルタ
18.2.2.8 単純化のステップ
18.2.3 マッピングされたグラフ・パターンの例
18.2.4 グループ、集約、HAVING、最後のVALUES句、SELECT式の変換
18.2.4.1 グルーピングと集約
18.2.4.2 HAVING
18.2.4.3 VALUES
18.2.4.4 SELECT式
18.2.5 ソリューション修飾子の変換
18.2.5.1 ORDER BY
18.2.5.2 射影
18.2.5.3 DISTINCT
18.2.5.4 REDUCED
18.2.5.5 OFFSETとLIMIT
18.2.5.6 最後の代数式
18.3 基本グラフ・パターン
18.3.1 SPARQLの基本グラフ・パターン・マッチング
18.3.2 空白ノードの処理
18.4 プロパティー・パス・パターン
18.5 SPARQL代数
18.5.1 集約代数
18.5.1.1 集合関数
18.5.1.2 Count
18.5.1.3 Sum
18.5.1.4 Avg
18.5.1.5 Min
18.5.1.6 Max
18.5.1.7 GroupConcat
18.5.1.8 Sample
18.6 評価セマンティクス
18.7 SPARQL基本グラフ・マッチングの拡張
18.7.1 注意
19 SPARQL文法
19.1 SPARQLリクエスト文字列
19.2 コードポイント・エスケープ・シーケンス
19.3 空白
19.4 コメント
19.5 IRI参照
19.6 空白ノードと空白ノード・ラベル
19.7 文字列中のエスケープ・シーケンス
19.8 文法
20 適合性
21 セキュリティに関する留意点(参考情報)
22 インターネット・メディア・タイプ、ファイル拡張子、およびマッキントッシュ・ファイル・タイプ
RDFは、ウェブ上で情報を表すための、有向性の、ラベル付けされたグラフ・データの形式です。RDFは、異なる情報源を統合する手段の提供に加え、とりわけ、個人的な情報、ソーシャル・ネットワーク、デジタル・アーティファクトに関するメタデータを表すためにしばしば使用されます。この仕様では、RDF用クエリ言語SPARQLの構文およびセマンティクスを定義しています。
RDF用クエリ言語SPARQLは、RDFデータ・アクセス・ユースケースおよび要件[UCNR]とSPARQL新機能と原理[UCNR2]でRDFデータ・アクセス・ワーキンググループが指定しているユースケースおよび要件を満たすように設計されています。
項の先頭で特に注記がなければ、このドキュメントのすべての項と付録は規範的です。
ドキュメントのこの項(1項)では、SPARQLクエリ言語の仕様を紹介します。この仕様ドキュメントの構成と、仕様で使用されている慣習を示します。
仕様の2項では、一連のクエリとクエリ結果の例により、SPARQLクエリ言語自体を紹介します。3項では、クエリの結果に現れるRDF用語において制約を表現するSPARQLの性能を示す例をより多く用いて、SPARQLクエリ言語の紹介を継続して行います。
4項では、SPARQLクエリ言語の構文の詳細を示します。これは、言語の完全な構文への手引きであり、文法構造がどのようにIRI、空白ノード、リテラル、変数を表すかを定義します。4項では、より冗長な表現に対する糖衣構文として役立ついくつかの文法構造の意味も定義します。
5項では、基本グラフ・パターンとグループ・グラフ・パターン、より複雑なSPARQLクエリ・パターンの構成要素を紹介します。6、7、8項では、SPARQLグラフ・パターンをより大きなグラフ・パターンに組み合わせる構成子を提示します。特に、6項では、クエリ・オプションの一部を作成する性能を紹介し、7項では、代替グラフ・パターンの論理和を表す性能を紹介し、8項では、情報の不在に関するテストを行うためのパターンを紹介します。
9項では、グラフ・パターン・マッチングにプロパティー・パスを追加し、クエリのコンパクトな表現に加え、グラフで任意の長さのパスにマッチングさせる性能を提供します。
10項では、SPARQLで可能な割り当ての形式について記述しています。
11項では、結果をグループ化して集約する方法を紹介します。これは、12項で述べているようなサブクエリとして組み込むことができます。
13項は、クエリの一部を特定のソース・グラフに制約する性能を紹介します。13項では、クエリに対してソース・グラフを定義するSPARQLの仕組みも提示します。
14項は、SPARQL 1.1統合クエリという別のドキュメントを参照します。
15項は、順序付け、スライス、プロジェクション、制限、ソリューションのシーケンスからの重複の排除によるクエリのソリューションに影響する構成子を定義します。
16項では、異なる形式の結果を生む4種類のSPARQLクエリを定義します。
17項では、SPARQLの拡張可能な値テストと式の枠組みを定義します。これは、クエリの結果に現われ、クエリが返す新しい値の演算も行う値を制約するために使用できる関数と演算子を提示します。
18項は、SPARQLグラフ・パターンとソリューション修飾子の評価に関する形式的な定義です。
19項は、EBNF表記法で示されている文法で規定されているような、SPARQLクエリ言語とSPARQL更新言語の構文の規範的な定義を含んでいます。
このドキュメントでは、特に注記がなければ、例では、次の名前空間は接頭辞バインディングを想定しています。
接頭辞 | IRI |
---|---|
rdf: |
http://www.w3.org/1999/02/22-rdf-syntax-ns# |
rdfs: |
http://www.w3.org/2000/01/rdf-schema# |
xsd: |
http://www.w3.org/2001/XMLSchema# |
fn: |
http://www.w3.org/2005/xpath-functions# |
sfn: |
http://www.w3.org/ns/sparql# |
このドキュメントでは、各トリプルを明示的に表示するためにTurtle[TURTLE]を使用します。Turtleでは、接頭辞を用いてIRIを省略することが認められています。
@prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix : <http://example.org/book/> . :book1 dc:title "SPARQL Tutorial" .
結果集合は、表形式で示されます。
「バインディング」は、(変数、RDF用語)の対です。この結果集合には、x
、y
、z
(列の見出しとして示されている)という3つの変数があります。各ソリューションは、表の本文の1つの列として示されています。ここでは、1つのソリューションがあり、変数x
は"Alice"
にバインドされており、変数y
は<http://example/a>
にバインドされており、変数z
はRDF用語にバインドされていません。ソリューションでは、変数は、バインドされている必要はありません。
SPARQL言語には、スペースを省略するRDF URI参照のサブセットであるIRIが含まれています。SPARQLクエリでは、すべてのIRIが絶対的であることに注意してください。IRIには、フラグメント識別子[RFC3987、3.1項]を含むことも含まないことも可能です。IRIには、URI[RFC3986]とURLが含まれます。SPARQL構文の省略形(相対IRIおよび接頭辞付き名前)が解決されると、絶対IRIが作成されます。
次の用語は、RDF概念および抽象構文 [CONCEPTS]で定義されており、SPARQLで使用されます。
RDF URI reference
)に対応)datatype URI
)という用語に対応)さらに、次の用語を定義しています。
SPARQLクエリのほとんどの形式には、基本グラフ・パターンと呼ばれる1組のトリプル・パターンが含まれています。それぞれの主語、述語、目的語が変数でありえることを除き、トリプル・パターンはRDFトリプルに類似しています。サブグラフからのRDF用語を変数に代替でき、結果がサブグラフに同等なRDFグラフである場合、基本グラフ・パターンはそのRDFデータのサブグラフにマッチします。
次の例は、与えられたデータ・グラフから書名(title)を発見するためのPARQLクエリを示しています。クエリは、次の2つで構成されています。SELECT
句はクエリの結果に現れる変数を識別し、WHERE
句はデータ・グラフにマッチする基本グラフ・パターンを提供します。この例の基本グラフ・パターンは、目的語の位置に1つの変数(?title
)を持つ、1つのトリプル・パターンから成ります。
クエリの結果は、クエリのグラフ・パターンがデータにマッチする方法に従ったソリューション・シーケンスです。クエリに対し、0、1または複数のソリューションがありえます。
データ:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Johnny Lee Outlaw" . _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Peter Goodguy" . _:b foaf:mbox <mailto:[email protected]> . _:c foaf:mbox <mailto:[email protected]> .
クエリ:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name . ?x foaf:mbox ?mbox }
クエリ結果:
name | mbox |
---|---|
"Johnny Lee Outlaw" | <mailto:[email protected]> |
"Peter Goodguy" | <mailto:[email protected]> |
各ソリューションは、クエリ・パターンがデータにマッチするように、選択された変数をRDF用語にバインドできる1つの方法を提示します。結果集合は、すべての可能なソリューションを示します。上例では、次の2つのデータのサブセットが2つのマッチをもたらしました。
_:a foaf:name "Johnny Lee Outlaw" . _:a foaf:box <mailto:[email protected]> .
_:b foaf:name "Peter Goodguy" . _:b foaf:box <mailto:[email protected]> .
これは、基本グラフ・パターン・マッチで、クエリ・パターンで使用されるすべての変数がすべてのソリューションにバインドされていなければなりません。
次のデータには、3つのRDFリテラルが含まれています。
@prefix dt: <http://example.org/datatype#> .
@prefix ns: <http://example.org/ns#> .
@prefix : <http://example.org/ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:x ns:p "cat"@en .
:y ns:p "42"^^xsd:integer .
:z ns:p "abc"^^dt:specialDatatype .
Turtleでは"cat"@en
が字句形式「cat」と言語タグ「en」を持つRDFリテラルであることに注意してください。"42"^^xsd:integer
は、データ型http://www.w3.org/2001/XMLSchema#integer
を持つ型付きリテラルであり、"abc"^^dt:specialDatatype
は、データ型http://example.org/datatype#specialDatatype
を持つ型付きリテラルです。
このRDFデータは、2.3.1~2.3.3項のクエリの例に用いるデータ・グラフです。
SPARQLの言語タグは、ベスト・コモン・プラクティス47[BCP47]で定められているように、@
と言語タグを用いて表されます。
次のクエリでは、"cat"
が"cat"@en
と同じRDFリテラルではないため、ソリューションはありません。
SELECT ?v WHERE { ?v ?p "cat" }
v |
---|
しかし、次のクエリは、言語タグが指定されており、与えられたデータにマッチするため、変数v
が:x
にバインドされているソリューションが見つかるでしょう。
SELECT ?v WHERE { ?v ?p "cat"@en }
v |
---|
<http://example.org/ns#x> |
SPARQLクエリの整数は、データ型xsd:integer
を持つRDF型付きリテラルです。例えば、42
は、"42"^^<http://www.w3.org/2001/XMLSchema#integer>
の省略形です。
次のクエリのパターンには、:y
にバインドされている変数v
を持つソリューションがあります。
4.1.2項では、xsd:float
とxsd:double
のSPARQL省略形を定義しています。
クエリの結果には、空白ノードを含むことができます。このドキュメントの例では、結果集合の空白ノードは、"_:"の後に空白ノード・ラベルが続く形で書かれています。
空白ノード・ラベルは結果集合(「SPARQLクエリ結果XMLフォーマット」と「SPARQL 1.1クエリ結果JSONフォーマット」を参照)で有効であり、CONSTRUCT
クエリ形式の場合は結果グラフで有効です。結果集合内での同じラベルの使用は、同じ空白ノードを表します。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:b foaf:name "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?x ?name WHERE { ?x foaf:name ?name }
上記の結果は、結果におけるラベルがソリューション内のRDF用語が同じか異なるかを示すだけであるため、異なる空白ノード・ラベルでも同じく得ることができます。
これらの2つの結果は同じ情報を持っていますが、2つのソリューションでは、クエリにマッチさせるために用いられる空白ノードが異なっています。結果集合のラベル_:a
と、同じラベルを持つデータ・グラフの空白ノードとの間に関係がある必要はありません。
アプリケーションの作成者は、クエリの空白ノード・ラベルがデータの特定の空白ノードを参照することを期待すべきではありません。
PARQL 1.1では、複数の式から値を作成できます。下記のクエリは、CONCAT関数をいて、foafデータの名と姓を連結させ、その後にSELECT
句内の式を用いて値を割り当て、さらにBIND形式を用いて値を割り当てる方法を示しています。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:givenName "John" . _:a foaf:surname "Doe" .
SPARQLには、いくつかのクエリ形式があります。SELECT
というクエリ形式は、変数バインディングを返します。CONSTRUCT
というクエリ形式はRDFグラフを返します。グラフは、クエリのグラフ・パターンをマッチングした結果に基づくRDFトリプルを作成するために用いられるテンプレートに基づいて構築されます。
データ:
@prefix org: <http://example.com/ns#> . _:a org:employeeName "Alice" . _:a org:employeeId 12345 . _:b org:employeeName "Bob" . _:b org:employeeId 67890 .
クエリ:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX org: <http://example.com/ns#> CONSTRUCT { ?x foaf:name ?name } WHERE { ?x org:employeeName ?name }
結果:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:x foaf:name "Alice" . _:y foaf:name "Bob" .
これは、次のとおり、RDF/XMLでシリアル化できます。
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:foaf="http://xmlns.com/foaf/0.1/" > <rdf:Description> <foaf:name>Alice</foaf:name> </rdf:Description> <rdf:Description> <foaf:name>Bob</foaf:name> </rdf:Description> </rdf:RDF>
グラフ・パターン・マッチングはソリューション・シーケンスを作成し、その各ソリューションは、RDF用語に対する変数バインディングの集合を持ちます。SPARQLのFILTER
は、フィルタの式が真(TRUE
)であるものにソリューションを制限します。
この項では、SPARQLのFILTER
に関する非形式的な手引きを提供します。このセマンティクスは、包括的な関数ライブラリがある「式と値のテスト」の項で定められています。この項の例では、次の1つの入力グラフを共用しています。
@prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix : <http://example.org/book/> . @prefix ns: <http://example.org/ns#> . :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 .
regex
のようなSPARQLのFILTER
関数は、RDFリテラルをテストできます。regex
は、文字列リテラルのみにマッチします。regex
は、str関数を用いて他のリテラルの字句形式にマッチさせるために使用できます。
クエリ:
PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?title WHERE { ?x dc:title ?title FILTER regex(?title, "^SPARQL") }
クエリ結果:
正規表現マッチでは、「i
」フラグを用いて大文字・小文字を区別しないようにすることができます。
クエリ:
PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?title WHERE { ?x dc:title ?title FILTER regex(?title, "web", "i" ) }
クエリ結果:
正規表現言語は、XQuery 1.0とXPath 2.0関数および演算子で定められており、XMLスキーマ正規表現に基づいています。
:book2
のみが30.5
未満の価格を持っているため、price
変数を制約することで、フィルタ条件の要求に従い、:book2
のみがクエリにマッチします。
数値型に加え、SPARQLは、xsd:string
、xsd:boolean
、xsd:dateTime
という型をサポートしています(オペランド・データ型を参照してください)。演算子マッピングの項では、演算子について述べ、関数の定義の項では、RDF用語に適用できる関数について述べています。
この項では、RDF用語およびトリプル・パターンに対してSPARQLが用いる構文をカバーしています。完全な文法は19項で示します。
iri生成規則は、IRI[RFC3987]の集合を指定します。IRIは、URI[RFC3986]を一般化したものであり、URIおよびURLと完全に互換性があります。PrefixedName生成規則は、接頭辞名を指定します。接頭辞名からIRIへのマッピングについて、以下で説明しています。IRI参照(相対的または絶対的なIRI)は、IRIREF生成規則によって指定され、「<」と「>」の区切り記号はIRI参照の一部にはなりません。相対IRIは、[RFC3987]の2.2 IRI参照とIRIに対するABNFの項のirelative-ref
にマッチし、下記のIRIに解決されます。
SPARQL用語にはIRIが含まれていますが、RDF概念および抽象構文で定義されているRDF用語にはRDF URI参照が含まれています。「<
」、「>
」、「"
」(ダブル引用符)、スペース、「{
」、「}
」、「|
」、「\
」、「^
」、「`
」を含むRDF URI参照は、IRIではありません。このようなRDF URI参照で構成されたRDFステートメントに対するSPARQLクエリの動作は定められていません。
PREFIX
キーワードは、接頭辞ラベルをIRIに関連付けます。接頭辞名は、コロン「:
」によって区切られた、接頭辞ラベルとローカル部分(local part)です。接頭辞名は、接頭辞に関連付けられたIRIとローカル部分とを連結することによって、IRIにマッピングされます。接頭辞ラベルまたはローカル部分は、空でありえます。先頭桁(leading digit)は、XMLローカル名では認められていませんが、SPARQLローカル名では認められていることに注意してください。SPARQLローカル名によって、バックスラッシュの文字エスケープ(例えば、ns:id\=123
)を用いると、IRIで認められている非英数字も使用可能になります。SPARQLローカル名には、CURIEよりも構文上の制限が多くあります。
相対IRIは、URI(Uniform Resource Identifier): 一般的構文[RFC3986]にあるとおり、5.2項の基本アルゴリズムのみを用いて、基底IRIに組み合わされます。構文に基づく正規化もスキームに基づく正規化も(RFC3986の6.2.2および6.2.3項に記述されている)実行されません。IRI参照で追加的に認められている文字は、IRI(Internationalized Resource Identifiers)[RFC3987]の6.5項にあるとおり、URI参照で無制限の文字が扱われているのと同じ方法で扱われます。
BASE
キーワードは、RFC3986の5.1.1項「コンテンツ内に組み込まれた基底URI」にあるとおり、相対IRIを解決するために用いられる基底IRIを定めます。5.1.2項「カプセル化されたエンティティーからの基底URI」は、xml:base指示子を持つSOAPエンベロープやContent-Locationヘッダーを持つマイム・マルチパート・ドキュメントのようなカプセル化されたドキュメントから、どのように基底IRIを持ってくることができるかを定めています。5.1.3「検索URIからの基底URI」で識別された「検索URI」は、特定のSPARQLクエリが検索されたURLです。上記のどれもが基底URIを指定しない場合は、デフォルト基底URI(5.1.4項「デフォルト基底URI」を参照)が用いられます。
次のフラグメントは、同じIRIを記述する別々の方法の一部です。
<http://example.org/book/book1>
BASE <http://example.org/book/> <book1>
PREFIX book: <http://example.org/book/> book:book1
リテラルの一般的な構文は、言語タグのオプション(@
で導入される)か、データ型IRIまたは接頭辞名のオプション(^^
で導入される)かのどちらかを持つ文字列(ダブル引用符"..."
、または、シングル引用符'...'
で囲まれた)です。
便宜上、整数を直接記述(引用符と明示的なデータ型IRIなしに)でき、これはデータ型xsd:integer
の型付きリテラルとして解釈され、数字の中に「.」があるけれども指数がない小数はxsd:decimal
と解釈され、指数がある数xsd:double
と解釈されます。型xsd:boolean
の値は、真(true
)または偽(false
)と記述できます。
自身に引用符を含む、または、長くて改行文字を含むリテラル値の記述を容易にするために、SPARQLでは、リテラルを3つのシングル引用符またはダブル引用符で囲んだ引用構成子も提供されています。
SPARQLのリテラル構文の例は、次のとおりです。
"chat"
'chat'@fr
"xyz"^^<http://example.org/ns/userDatatype>
"abc"^^appNS:appDataType
'''The librarian said, "Perhaps you would enjoy 'War and Peace'."'''
1
、これは"1"^^xsd:integer
と同じ1.3
、 これは"1.3"^^xsd:decimal
と同じ1.300
、 これは"1.300"^^xsd:decimal
と同じ1.0e6
、 これは"1.0e6"^^xsd:double
と同じtrue
、 これは"true"^^xsd:boolean
と同じfalse
、 これは"false"^^xsd:boolean
と同じ生成規則INTEGER、DECIMAL、DOUBLE、BooleanLiteralにマッチするトークンは、トークンの字句値と、対応するデータ型(xsd:integer
、xsd:decimal
、xsd:double
、xsd:boolean
)を持つ型付きテラルと同等です。
クエリ変数は「?」か「$」のどちらを用いてマーク付けされますが、「?」や「$」は変数名の一部ではありません。クエリでは、$abc
と?abc
は同じ変数を識別します。SPARQL文法では、変数に対して可能な名前が与えられます。
グラフ・パターンの空白ノードは、問い合わされたデータの特定の空白ノードの参照としてではなく、変数として機能します。
空白ノードは、「_:abc
」などのラベル形式か、省略形「[]
」のどちらかで示されます。クエリ構文の1箇所でしか使うことができない空白ノードは[]
で示すことができます。ユニークな空白ノードは、トリプル・パターンを形成するために用いられるでしょう。ラベル「abc
」を持つ空白ノードに対する空白ノード・ラベルは「_:abc
」と書かれます。同じ空白ノード・ラベルは、同じクエリ内の2つの異なる基本グラフ・パターンに使用することはできません。
[:p :v]
構成子は、トリプル・パターンで用いることができます。これは、すべてを含んだ述語-目的語の対の主語として用いられる空白ノード・ラベルを作成します。作成された空白ノードは、さらに他のトリプル・パターンの主語と目的語の位置でも使用できます。
次の2つの形式
[ :p "v" ] .
[] :p "v" .
は、ユニークな空白ノード・ラベル(ここでは「b57
」)を割り当てると、次の記述と同等です。
_:b57 :p "v" .
割り当てられたこの空白ノード・ラベルは、さらに別のトリプル・パターンの主語または目的語として使用できます。例えば、主語として用いると次のようになります。
[ :p "v" ] :q "w" .
これは、次の2つのトリプルと同等です。
_:b57 :p "v" . _:b57 :q "w" .
そして、目的語として用いると次のようになります。
:x :q [ :p "v" ] .
これは、次の2つのトリプルと同等です。
:x :q _:b57 . _:b57 :p "v" .
省略化された空白ノード構文は、共通の主語と共通の述語に対する他の省略語と組み合わせることができます。
[ foaf:name ?name ; foaf:mbox <mailto:[email protected]> ]
これは、あるユニークに割り当てられた空白ノード・ラベル「b18
」に対する次の基本グラフ・パターンの記述と同じです。
_:b18 foaf:name ?name . _:b18 foaf:mbox <mailto:[email protected]> .
トリプル・パターンは、主語、述語、目的語として書かれます。いくつかの共通するトリプル・パターン構成子を省略して書く方法があります。
次の例は、同じクエリを表します。
PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?title WHERE { <http://example.org/book/book1> dc:title ?title }
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> SELECT $title WHERE { :book1 dc:title $title }
BASE <http://example.org/book/> PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT $title WHERE { <book1> dc:title ?title }
共通の主語を持つトリプル・パターンは、主語を1度だけ記述し、「;
」表記法を用いて1つ以上のトリプル・パターンで用いられるように記述できます。
?x foaf:name ?name ; foaf:mbox ?mbox .
これは、次のトリプル・パターンの記述と同じです。
?x foaf:name ?name . ?x foaf:mbox ?mbox .
トリプル・パターンが主語と述語の両方を共有する場合、目的語を「,
」で区切ることができます。
?x foaf:nick "Alice" , "Alice_" .
上記は、次のトリプル・パターンの記述と同じです。
?x foaf:nick "Alice" . ?x foaf:nick "Alice_" .
次のように、目的語のリストを述語-目的語のリストと組み合わせることができます。
?x foaf:name ?name ; foaf:nick "Alice" , "Alice_" .
これは、次と同等です。
?x foaf:name ?name . ?x foaf:nick "Alice" . ?x foaf:nick "Alice_" .
「(element1 element2 ...)」という構文を用いてトリプル・パターンにRDFコレクションを記述できます。形式「()
」は、http://www.w3.org/1999/02/22-rdf-syntax-ns#nil
というIRIの代替です。(1 ?x 3 4)
のようなコレクション要素とともに用いれば、空白ノードを持つトリプル・パターンがコレクションに割り当てられます。コレクションの先頭の空白ノードは、他のトリプル・パターンの主語または目的語として使用できます。コレクション構文で割り当てられた空白ノードは、クエリのほかの場所では出現しません。
(1 ?x 3 4) :p "w" .
上記は、次に対する糖衣構文です(b0
、b1
、b2
、b3
がクエリの他のどこかで出現しないことを意味する)。
_:b0 rdf:first 1 ; rdf:rest _:b1 . _:b1 rdf:first ?x ; rdf:rest _:b2 . _:b2 rdf:first 3 ; rdf:rest _:b3 . _:b3 rdf:first 4 ; rdf:rest rdf:nil . _:b0 :p "w" .
RDFコレクションは、入れ子にすることができ、他の構文を含むことができます。
(1 [:p :q] ( 2 ) ) .
上記は、次に対する糖衣構文です。
_:b0 rdf:first 1 ; rdf:rest _:b1 . _:b1 rdf:first _:b2 . _:b2 :p :q . _:b1 rdf:rest _:b3 . _:b3 rdf:first _:b4 . _:b4 rdf:first 2 ; rdf:rest rdf:nil . _:b3 rdf:rest rdf:nil .
キーワード「a
」は、トリプル・パターンで述語として使用でき、http://www.w3.org/1999/02/22-rdf-syntax-ns#type
というIRIの代替です。このキーワードは大文字・小文字を区別します。
?x a :Class1 . [ a :appClass ] :p "v" .
上記は、次に対する糖衣構文です。
?x rdf:type :Class1 . _:b0 rdf:type :appClass . _:b0 :p "v" .
SPARQLはグラフ・パターン・マッチングを基本としています。より複雑なグラフ・パターンは、小さなパターンを様々な方法で組み合わせて作成できます。
この項では、論理積でパターンを組み合わせる2つの形式について説明します。それらは、トリプル・パターンを組み合わせる基本グラフ・パターンと、他のすべてのパターンを組み合わせるグループ・グラフ・パターンです。
最も外側のクエリのグラフ・パターンは、クエリ・パターンと呼ばれます。これは、文法上、次のGroupGraphPattern
で識別されます。
[17] |
WhereClause |
::= | 'WHERE'? GroupGraphPattern |
基本グラフ・パターンはトリプル・パターンの集合です。SPARQLのグラフ・パターン・マッチングは、マッチした基本グラフ・パターンの結果を組み合わせるという観点で定義されます。
オプションのフィルタを有する、トリプル・パターンのシーケンスは、1つの基本グラフ・パターンから成ります。他のグラフ・パターンが、基本グラフ・パターンを終了させます。
形式_:abc
の空白ノードを用いるときには、空白ノードのラベルは基本グラフ・パターンで有効です。1つのラベルは、任意のクエリにおける1つの基本グラフ・パターンのみで使用できます。
SPARQLは、サブグラフ・マッチングで基本グラフ・パターンを評価します。これは、シンプルな含意のために定義されています。以下の記述のような、ある特定の状況が与えられれば、SPARQLを他の形式の含意に拡張できます。SPARQL 1.1含意レジームのドキュメントは、いくつかの特定の含意レジームについて記述しています。
SPARQLのクエリ文字列では、グループ・グラフ・パターンは中括弧({}
)で区切られます。例えば、このクエリのクエリ・パターンは、1つの基本グラフ・パターンからなるグループ・グラフ・パターンです。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name . ?x foaf:mbox ?mbox . }
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { { ?x foaf:name ?name . } { ?x foaf:mbox ?mbox . } }
グループ・パターン
{ }
は、任意のグラフ(空のグラフを含む)を、変数をバインドしない1つのソリューションにマッチさせます。例えば、
SELECT ?x WHERE {}
は、変数x
がバインドされていない1つのソリューションとマッチします。
FILTER
キーワードによって表される制約は、フィルタが出現するすべてのグループにまたがるソリューションに対する制限です。次のパターンはすべて、同じソリューションを持ちます。
{ ?x foaf:name ?name . ?x foaf:mbox ?mbox . FILTER regex(?name, "Smith") }
{ FILTER regex(?name, "Smith") ?x foaf:name ?name . ?x foaf:mbox ?mbox . }
{ ?x foaf:name ?name . FILTER regex(?name, "Smith") ?x foaf:mbox ?mbox . }
{ ?x foaf:name ?name . ?x foaf:mbox ?mbox . }
は、1つの基本グラフ・パターンからなるグループで、その基本グラフ・パターンは、2つのトリプル・パタ ーンから構成されています。
{ ?x foaf:name ?name . FILTER regex(?name, "Smith") ?x foaf:mbox ?mbox . }
は、1つの基本グラフ・パターンとフィルタからなるグループで、その基本グラフ・パターンは、2つのトリプル・パターンから構成されています。フィルタは基本グラフ・パターンを2つの基本グラフ・パターンに分割しません。
{ ?x foaf:name ?name . {} ?x foaf:mbox ?mbox . }
は、1つのトリプル・パターンからなる基本グラフ・パターン、空のグループ、1つのトリプル・パターンからなる別の基本グラフ・パターンという、3つの要素のグループです。
基本グラフ・パターンでは、アプリケーションは、ソリューションが生成されるようにクエリ・パターンの全体がマッチしなければならないようなクエリを作成できます。少なくとも1つの基本グラフ・パターンを持つグループ・グラフ・パターンのみを含むクエリのすべてのソリューションでは、すべての変数は、あるソリューションのあるRDF用語にバインドされます。しかし、すべてのRDFグラフにおいて、正規の、完全な構成を想定することはできません。情報が利用できるソリューションに情報を追加できるクエリを持つことができると便利ですが、クエリ・パターンの一部がマッチしないという理由でソリューションを拒絶すべきではありません。オプションのマッチングは、この機能を提供します。オプション部分がマッチしない場合は、バインディングを作成しませんが、ソリューションは排除しません。
グラフ・パターンのオプション部分は、次のグラフ・パターンに当てはまるOPTIONALキーワードで構文的に指定されます。
pattern OPTIONAL { pattern }
構文形式
{ OPTIONAL { pattern } }
は次と同等です。
{ { } OPTIONAL { pattern } }
OPTIONAL
キーワードは左結合的で、
pattern OPTIONAL { pattern } OPTIONAL { pattern }
次と同じです。
{ pattern OPTIONAL { pattern } } OPTIONAL { pattern }
オプションのマッチでは、オプションのグラフ・パターンがグラフにマッチし、その結果、1つ以上のソリューションに対し、バインディングを定義し追加するか、追加のバインディングを加えずにソリューションをそのままにします。
データ:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . _:a rdf:type foaf:Person . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> . _:a foaf:mbox <mailto:[email protected]> . _:b rdf:type foaf:Person . _:b foaf:name "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name . OPTIONAL { ?x foaf:mbox ?mbox } }
上記のデータを用いると、クエリ結果は次の通りです。
name | mbox |
---|---|
"Alice" | <mailto:[email protected]> |
"Alice" | <mailto:[email protected]> |
"Bob" |
名前が"Bob"
であるソリューションのmbox
の値はありません。
このクエリはデータ内の人名を発見します。述語mbox
と、同じ主語を持つトリプルがある場合、ソリューションにはそのトリプルの目的語も含まれるでしょう。この例では、クエリのオプションのマッチ部分では1つのトリプル・パターンのみが得られますが、一般に、オプションの部分は任意のグラフ・パターンでありえます。オプションのグラフ・パターンの全体は、クエリのソリューションに影響するように、オプションのグラフ・パターンにマッチしなければなりません。
オプションのグラフ・パターンでは、制約を付与できます。例えば、次のとおりです。
@prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix : <http://example.org/book/> . @prefix ns: <http://example.org/ns#> . :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 .
「SPARQL Tutorial」というタイトルの本には、価格が表示されません。なぜならば、オプションのグラフ・パターンが変数「price
」を伴うソリューションをもたらさなかったからです。
グラフ・パターンは再帰的に定義されます。グラフ・パターンは0以上のオプションのグラフ・パターンを持つことができ、クエリ・パターンのどの部分もオプション部分を持つことができます。この例には、2つのオプションのグラフ・パターンがあります。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:homepage <http://work.example.org/alice/> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox ?hpage WHERE { ?x foaf:name ?name . OPTIONAL { ?x foaf:mbox ?mbox } . OPTIONAL { ?x foaf:homepage ?hpage } }
クエリ結果:
name | mbox | hpage |
---|---|---|
"Alice" | <http://work.example.org/alice/> | |
"Bob" | <mailto:[email protected]> |
SPARQLは、いくつかの代替グラフ・パターンの1つがマッチするようにグラフ・パターンを組み合わせる方法を備えています。1つ以上の代替がマッチすれば、すべてのありえるパターンのソリューションが見つかります。
パターン代替は、UNION
キーワードで構文的に指定されます。
@prefix dc10: <http://purl.org/dc/elements/1.0/> . @prefix dc11: <http://purl.org/dc/elements/1.1/> . _:a dc10:title "SPARQL Query Language Tutorial" . _:a dc10:creator "Alice" . _:b dc11:title "SPARQL Protocol Tutorial" . _:b dc11:creator "Bob" . _:c dc10:title "SPARQL" . _:c dc11:title "SPARQL (updated)" .
PREFIX dc10: <http://purl.org/dc/elements/1.0/> PREFIX dc11: <http://purl.org/dc/elements/1.1/> SELECT ?title WHERE { { ?book dc10:title ?title } UNION { ?book dc11:title ?title } }
クエリ結果:
このクエリは、バージョン1.0、バージョン1.1のどちらのダブリン・コアのプロパティーを用いてタイトルが記録されているかに関係なく、データ中の本のタイトルを発見します。情報の記録方法を厳密に判別するために、クエリは2つの代替に対して異なる変数を用いることができます。
PREFIX dc10: <http://purl.org/dc/elements/1.0/> PREFIX dc11: <http://purl.org/dc/elements/1.1/> SELECT ?x ?y WHERE { { ?book dc10:title ?x } UNION { ?book dc11:title ?y } }
これは、UNION
の左辺のソリューションにバインドされた変数x
と、右辺のソリューションにバインドされたy
を持った結果を返すでしょう。UNION
パターンのどちらの部分にもマッチしない場合、グラフ・パターンはマッチしないでしょう。
UNION
パターンはグラフ・パターンを組み合わせます。それぞれの代替に、1つ以上のトリプル・パターンを含むことができます。
PREFIX dc10: <http://purl.org/dc/elements/1.0/> PREFIX dc11: <http://purl.org/dc/elements/1.1/> SELECT ?title ?author WHERE { { ?book dc10:title ?title . ?book dc10:creator ?author } UNION { ?book dc11:title ?title . ?book dc11:creator ?author } }
ダブリン・コアの同じバージョンのタイトルと著者の両方の述語がある場合にのみ、このクエリは本にマッチするでしょう。
SPARQLクエリ言語には、2つの形式の否定が組み込まれています。1つは、フィルタリング結果に基づくもので、グラフ・パターンがフィルタリングされるクエリ・ソリューションのコンテキストにおいてマッチするか否かに依存します。もう1つは、別のパターンと関係のあるソリューションの除外に基づくものです。
クエリ・ソリューションのフィルタリングは、FILTER
式内でNOT EXISTS
とEXISTS
を用いて行います。フィルタの範囲の規則がフィルタが出現するすべてのグループに適用されることに注意してください。
NOT EXISTS
というフィルタ式は、フィルタが存在するグループ・グラフ・パターンの変数の値が与えられた場合に、グラフ・パターンがデータセットと一致するか否かをテストします。これによって、追加のバインディングは作成されません。
データ:
@prefix : <http://example/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . :alice rdf:type foaf:Person . :alice foaf:name "Alice" . :bob rdf:type foaf:Person .
クエリ:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?person WHERE { ?person rdf:type foaf:Person . FILTER NOT EXISTS { ?person foaf:name ?name } }
クエリ結果:
person |
---|
<http://example/bob> |
EXISTS
というフィルタ式も提供されています。これは、データ内でパターンが発見できるか否かをテストします。これによって、追加のバインディングは作成されません。。
クエリ:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?person WHERE { ?person rdf:type foaf:Person . FILTER EXISTS { ?person foaf:name ?name } }
クエリ結果:
person |
---|
<http://example/alice> |
SPARQLが提供する別の形式の否定はMINUS
で、両方の引数を評価した後に、右側のソリューションと互換性がない左側のソリューションを割り出します。
@prefix : <http://example/> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . :alice foaf:givenName "Alice" ; foaf:familyName "Smith" . :bob foaf:givenName "Bob" ; foaf:familyName "Jones" . :carol foaf:givenName "Carol" ; foaf:familyName "Smith" .
PREFIX : <http://example/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT DISTINCT ?s WHERE { ?s ?p ?o . MINUS { ?s foaf:givenName "Bob" . } }
結果:
s |
---|
<http://example/carol> |
<http://example/alice> |
NOT EXISTS
とMINUS
は、否定に関する2つの考え方を表しています。1つは、バインディングがクエリ・パターンによって既に決定されている場合に、データ内にパターンが存在するか否かのテストに基づくもので、もう1つは、2つのパターンの評価に基づくマッチの除外に基づくものです。場合によっては、これらは異なる答えを出す可能性があります。
@prefix : <http://example/> . :a :b :c .
SELECT * { ?s ?p ?o FILTER NOT EXISTS { ?x ?y ?z } }
これは、{ ?x ?y ?z }
が任意の?s ?p ?o
とマッチし、したがって、NOT EXISTS { ?x ?y ?z }
が任意のソリューションを排除するため、ソリューションのない結果集合となります。
s | p | o |
---|
一方で、MINUS
の場合、最初の(?s ?p ?o
)と2番目の(?x ?y ?z
)との間には共有する変数がないため、バインディングは排除されません。
SELECT * { ?s ?p ?o MINUS { ?x ?y ?z } }
結果:
s | p | o |
---|---|---|
<http://example/a> | <http://example/b> | <http://example/c> |
別のケースは、例に具体的なパターン(変数ではない)がある場合です。
PREFIX : <http://example/> SELECT * { ?s ?p ?o FILTER NOT EXISTS { :a :b :c } }
これは、クエリ・ソリューションのない結果集合となります。
結果:s | p | o |
---|
一方で、
PREFIX : <http://example/> SELECT * { ?s ?p ?o MINUS { :a :b :c } }
は、1つのクエリ・ソリューションがある結果集合となります。
結果:
s | p | o |
---|---|---|
<http://example/a> | <http://example/b> | <http://example/c> |
これは、バインディングのマッチがなく、したがって、ソリューションが排除されないためです。
フィルタでは、グループからの変数が範囲内(in scope)であるという理由からも、違いは生じます。この例では、NOT EXISTS
内のFILTER
は、対象のソリューションに対し?nという値を利用できます。
@prefix : <http://example.com/> . :a :p 1 . :a :q 1 . :a :q 2 . :b :p 3.0 . :b :q 4.0 . :b :q 5.0 .
FILTER NOT EXISTS
を用いた場合、テストは、?x :p ?n
の個々のソリューションに関するものです。
PREFIX : <http://example.com/> SELECT * WHERE { ?x :p ?n FILTER NOT EXISTS { ?x :q ?m . FILTER(?n = ?m) } }
x | n |
---|---|
<http://example.com/b> | 3.0 |
一方で、MINUS
の場合、パターン内のFILTER
は、?nに対する値を持たず、常にバインドされません。
PREFIX : <http://example/> SELECT * WHERE { ?x :p ?n MINUS { ?x :q ?m . FILTER(?n = ?m) } }
x | n |
---|---|
<http://example.com/b> | 3.0 |
<http://example.com/a> | 1 |
プロパティー・パスは、2つのグラフ・ノード間のグラフ上の経路です。簡単な例は、きっかり1の長さのプロパティー・パスで、これはトリプル・パターンです。パスの終点は、RDF用語か変数でありえます。変数をパス自体の一部として用いることはできず、終点としてのみ用いることができます。
プロパティー・パスにより、一部のSPARQLの基本グラフ・パターンに対し、より簡潔な表現が可能となり、任意の長さのパスで2つの資源の連結とマッチする性能が追加されます。
下記の記述では、iriは、完全形か接頭辞付き名前で省略したIRI、または、キーワードaのいずれかです。eltはパス要素で、それ自体をパス構成子で構成することができます。
構文形式 | プロパティー・パス式名 | マッチ |
---|---|---|
iri | PredicatePath | IRI。長さ1のパス。 |
^elt | InversePath | 逆パス(主語から述語)。 |
elt1 / elt2 | SequencePath | elt2が後続するelt1のシーケンス・パス。 |
elt1 | elt2 | AlternativePath | elt1またはelt2の代替パス(すべての可能性が試みられる)。 |
elt* | ZeroOrMorePath | 0以上のeltのマッチでパスの主語と目的語を結合するパス。 |
elt+ | OneOrMorePath | 1つ以上のeltのマッチでパスの主語と目的語を結合するパス。 |
elt? | ZeroOrOnePath | 0または1つのeltのマッチでパスの主語と目的語を結合するパス。 |
!iri or !(iri1| ...|irin) | NegatedPropertySet | 否定のプロパティー集合。iriiの1つではないIRI。!iriは!(iri)の省略形。 |
!^iri or !(^iri1| ...|^irin) | NegatedPropertySet | 除外されたマッチが逆パスに基づく場合の、否定のプロパティー集合。 つまり、逆パスとしてiri1...irinの1つではない。!^iriは、!(^iri)の省略形。 |
!(iri1| ...|irij|^irij+1| ...|^irin) | NegatedPropertySet | 否定のプロパティー集合のforwardおよびreverseプロパティーの組み合わせ。 |
(elt) | グループ・パスelt、括弧コントロール優先。 |
否定のプロパティー集合のIRIや逆のIRIの順序は重要ではなく、それらは混在した順序で出現する場合があります。
構文形式の優先順位は、次の上から下への順です。
グループ内の優先順位は、左から右です。
選択肢: 片方または両方とマッチします。
{ :book1 dc:title|rdfs:label ?displayString }
これは、次のように記述することが可能でした。
{ :book1 <http://purl.org/dc/elements/1.1/title> | <http://www.w3.org/2000/01/rdf-schema#label> ?displayString }
シーケンス: アリスが知っているあらゆる人々の名前を見つけます。
{ ?x foaf:mbox <mailto:alice@example> . ?x foaf:knows/foaf:name ?name . }
シーケンス: 「foaf:knows」が2リンク離れた人々の名前を見つけます。
{ ?x foaf:mbox <mailto:alice@example> . ?x foaf:knows/foaf:knows/foaf:name ?name . }
これは、次のSPARQLクエリと同じです。
SELECT ?x ?name { ?x foaf:mbox <mailto:alice@example> . ?x foaf:knows [ foaf:knows [ foaf:name ?name ]]. }
あるいは、変数を明示的に用いると、次のとおりです。
SELECT ?x ?name { ?x foaf:mbox <mailto:alice@example> . ?x foaf:knows ?a1 . ?a1 foaf:knows ?a2 . ?a2 foaf:name ?name . }
重複のフィルタリング: アリスが知っている人はおそらくアリスを知っているため、上記の例にはアリス自身が含まれている可能性があります。これは、次の方法で回避できます。
{ ?x foaf:mbox <mailto:alice@example> . ?x foaf:knows/foaf:knows ?y . FILTER ( ?x != ?y ) ?y foaf:name ?name }
逆プロパティー・パス: これらの2つは同じクエリです。2番目は、主語と目的語の役割を取り替え、プロパティーの方向を正反対にしています。
{ ?x foaf:mbox <mailto:alice@example> }
{ <mailto:alice@example> ^foaf:mbox ?x }
逆パス・シーケンス: ?xが知っている人を知っている人々をすべて見つけます。
{ ?x foaf:knows/^foaf:knows ?y . FILTER(?x != ?y) }
これは、次と同等です(?gen1
はシステムが生成した変数)
{ ?x foaf:knows ?gen1 . ?y foaf:knows ?gen1 . FILTER(?x != ?y) }
任意の長さのマッチ: foaf:knowsによってアリスから到達可能なすべての人々の名前を見つけます。
{ ?x foaf:mbox <mailto:alice@example> . ?x foaf:knows+/foaf:name ?name . }
任意の長さのパスの代替:
{ ?ancestor (ex:motherOf|ex:fatherOf)+ <#me> }
任意の長さのパス・マッチ: 同じく、一部の制限付き推論の形式も可能です。例えば、RDFSの場合、資源のすべてのタイプとスーパータイプ:
{ <http://example/thing> rdf:type/rdfs:subClassOf* ?type }
すべての資源およびそのすべての推論されるタイプ:
{ ?x rdf:type/rdfs:subClassOf* ?type }
サブプロパティー:
{ ?x ?p ?v . ?p rdfs:subPropertyOf* :property }
否定のプロパティー・パス: 結合しているノードを見つけますが、rdf:type(または、逆のrdf:type)によってではありません。
{ ?x !(rdf:type|^rdf:type) ?y }
RDFコレクションの要素:
{ :list rdf:rest*/rdf:first ?element }
注意: このパス式では、結果の順序を保証されません。
SPARQLプロパティー・パスは、RDFトリプルを、有向性の、巡回的である可能性のある、名前付きの辺を有するグラフとして扱います。一部のプロパティー・パスは、トリプル・パターンおよびSPARQL UNIONグラフ・パターンへの置換と同等です。同等のパターンに導入された変数は結果の一部でなく、他では未使用であるため、プロパティー・パス式の評価は重複につながる場合があります。それらは、クエリで得られた変数のみへの結果の暗黙的な射影によって非表示になります。
例えば、次のデータでは:
@prefix : <http://example/> . :order :item :z1 . :order :item :z2 . :z1 :name "Small" . :z1 :price 5 . :z2 :name "Large" . :z2 :price 5 .
クエリ:
PREFIX : <http://example/> SELECT * { ?s :item/:price ?x . }
結果:
s | x |
---|---|
<http://example/order> | 5 |
<http://example/order> | 5 |
一方で、クエリが中間変数(?_a
)を含めるように記述されていれば、結果の中の列は重複しません。
PREFIX : <http://example/> SELECT * { ?s :item ?_a . ?_a :price ?x . }
結果:
s | _a | x |
---|---|---|
<http://example/order> | <http://example/z1> | 5 |
<http://example/order> | <http://example/z2> | 5 |
クエリに集約の操作も含まれている場合、グラフ・パターンに対する同等性は特に重要です。注文の総額は、以下のとおりです。
PREFIX : <http://example/> SELECT (sum(?x) AS ?total) { :order :item/:price ?x }
total |
---|
10 |
任意の長さのプロパティー・パスによる主語と目的語の結合性は、「0以上」のプロパティー・パス演算子である*
と、「1以上」のプロパティー・パス演算子である+
を用いて見つけることができます。「0または1」の結合プロパティー・パス演算子である?
もあります。
これらの個々の演算子は、演算子で制限されているとおりに、パスのステップを繰り返し用いて、プロパティー・パス式により主語と目的語の結合の発見を試みます。
例えば、資源のスーパータイプを含む、ありえるすべてのタイプの資源は、次の記述で発見できます。
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> . PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> SELECT ?x ?type { ?x rdf:type/rdfs:subClassOf* ?type }
同様に、すべての人々:x
の発見は、foaf:knows
の関係により結合します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX : <http://example/> SELECT ?person { :x foaf:knows+ ?person }
パスの繰り返し自体により重複が発生することはあっても、この結合性のマッチングにより重複が発生することはありません(これには、結合を生成できる方法の数は含まれてはいません)。
マッチしたグラフには、循環が含まれる可能性があります。結合性マッチングは、マッチングの循環によって、未定義や無限の結果が生じないように定義されています。
新しい変数を式の値にバインドすることにより、式の値をソリューション・マッピングに追加することができ、これはRDF用語となります。その後、変数はクエリで使用でき、結果として返すこともできます。
これは、BIND
キーワード、 SELECT
句の式、GROUP BY
句の式という3つの構文形式で可能です。割り当ての形式は、(expression AS ?var)
です。
式の評価がエラーとなった場合には、変数はそのソリューションにバインドされないままとなりますが、クエリの評価は継続します。
直接VALUES
をインライン・データに用いて、データをクエリに含むこともできます。
BIND
形式により、基本グラフ・パターンまたはプロパティー・パス式の変数への値の割り当てが可能となります。BIND
の使用によって、先行する基本グラフ・パターンは終了します。BIND
句によって導入される変数が、BIND
の使用前に、グループ・グラフ・パターンで使用されていることはありません。
例:
データ:
@prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix : <http://example.org/book/> . @prefix ns: <http://example.org/ns#> . :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book1 ns:discount 0.2 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 . :book2 ns:discount 0.25 .
クエリ:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX ns: <http://example.org/ns#> SELECT ?title ?price { ?x ns:price ?p . ?x ns:discount ?discount BIND (?p*(1-?discount) AS ?price) FILTER(?price < 20) ?x dc:title ?title . }
同等のクエリ(BIND
により、基本グラフ・パターンは終了します。FILTER
は、グループ・グラフ・パターンの全体に適用されます。)
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX ns: <http://example.org/ns#> SELECT ?title ?price { { ?x ns:price ?p . ?x ns:discount ?discount BIND (?p*(1-?discount) AS ?price) } {?x dc:title ?title . } FILTER(?price < 20) }
結果:
title | price |
---|---|
?"The Semantic Web" | 17.25 |
データは、VALUESを用いて、グラフ・パターンに直接記述するか、クエリに追加することができます。VALUES
は、インライン・データを、joinオペレーションによるクエリ評価の結果と結合したソリューション・シーケンスとして提供します。これは、アプリケーションに用いてクエリ結果に特定の要件を提供することができ、また、SERVICE
キーワードで統合クエリを提供するSPARQLのクエリ・エンジンの実装に用いて、遠隔のクエリ・サービスに対してより制約のあるクエリを送信することもできます。
VALUES
により、データ・ブロックで複数の変数を指定することができます。たった1つの変数と複数の値を指定するという一般的なケースに対しては、特別な構文があります。
次の例には、?x
と?y
の2つの変数から成る表があります。2列目には?y
に対する値がありません。
VALUES (?x ?y) { (:uri1 1) (:uri2 UNDEF) }
別の方法として、次のように、1つの変数と複数の値がある場合、
VALUES ?z { "abc" "def" }
これは、次の一般的な形式を用いるのと同じです。
VALUES (?z) { ("abc") ("def") }
データのVALUES
ブロックは、クエリ・パターン、または、サブクエリを含むSELECT
クエリの終点に出現可能です。
データ:
@prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix : <http://example.org/book/> . @prefix ns: <http://example.org/ns#> . :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 .
クエリ:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> SELECT ?book ?title ?price { VALUES ?book { :book1 :book3 } ?book dc:title ?title ; ns:price ?price . }
結果:
VALUES
句において、変数が特別なソリューションに対する値を持っていない場合は、RDF用語ではなくキーワードUNDEF
が用いられます。
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> SELECT ?book ?title ?price { ?book dc:title ?title ; ns:price ?price . VALUES (?book ?title) { (UNDEF "SPARQL Tutorial") (:book2 UNDEF) } }
book | title | price |
---|---|---|
<http://example.org/book/book1> | "SPARQL Tutorial" | 42 |
<http://example.org/book/book2> | "The Semantic Web" | 23 |
この例では、VALUES
はSELECT
クエリの結果に対して実行するように指定されていたかもしれません。
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> SELECT ?book ?title ?price { ?book dc:title ?title ; ns:price ?price . } VALUES (?book ?title) { (UNDEF "SPARQL Tutorial") (:book2 UNDEF) }
これは異なるクエリですが、この例では、同じ結果となります。
集約(aggregate)は、グループのソリューションに対して式を適用します。デフォルトでは、ソリューションの集合は1つのグループで構成され、すべてのソリューションを含んでいます。
グループは、GROUP BY
構文で指定できます。
SPARQLのバージョン1.1で定義されている集約は、COUNT
、SUM
、MIN
、MAX
、AVG
、GROUP_CONCAT
とSAMPLE
です。
集約は、クエリの実行者が、1つのソリューションではなく、ソリューションのグループに対する演算結果を求めている場合に用いられます。例えば、個々の値ではなく、特定の変数が取る最大値などです。
データ:
@prefix : <http://books.example/> . :org1 :affiliates :auth1, :auth2 . :auth1 :writesBook :book1, :book2 . :book1 :price 9 . :book2 :price 5 . :auth2 :writesBook :book3 . :book3 :price 7 . :org2 :affiliates :auth3 . :auth3 :writesBook :book4 . :book4 :price 7 .
クエリ:
PREFIX : <http://books.example/> SELECT (SUM(?lprice) AS ?totalPrice) WHERE { ?org :affiliates ?auth . ?auth :writesBook ?book . ?book :price ?lprice . } GROUP BY ?org HAVING (SUM(?lprice) > 10)
結果:
totalPrice |
---|
21 |
この例では、集約の2つの機能を示しています。GROUP BY
は、1つ以上の式(このケースでは、?org
)に従ってクエリ・ソリューションをグループ化します。また、HAVING
は、FILTER
式に似てていますが、個々のソリューションではなくグループに対して機能します。
例は、GROUP BY
式でソリューションをグループ化し(つまり、?org
が特定の値を取るすべてのソリューションは、同じグループ内に出現する)、そのグループに対し集合関数SUM
で評価して作成されています。その後、グループはHAVING
式でフィルタリングされ、SUM(?lprice)
によって、10以下のグループがすべて削除されます。
集約クエリとサブクエリでは、クエリ・パターンには出現するけれどもGROUP BY
句内には存在しない変数は、集約される場合には、単に射影することも、選択式で使用することもできます。SAMPLE
集約は、この目的に使用できます。詳細については、射影制限の項を参照してください。
関数に従って、クエリまたはサブクエリから射影するためには、集約式を別名にする必要がある(ここでも、BIND
句と同様に、キーワードAS
を用いる)ということに注意すべきです。上例では、これは変数?totalPrice
を用いて行われます。他の集約の射影やWHERE
句で既に使用されている名前を有する変数を集約が射影するとエラーとなります。
ソリューションに対する集約の値を計算するため、最初にソリューションを1つ以上のグループに分割し、各グループに対して集約の値を算出します。
集約がSELECT
、HAVING
やORDER BY
のクエリ・レベルで用いられていても、GROUP BY
用語が用いられていなければ、すべてのソリューションが属する1つの暗黙的なグループと見なされます。
GROUP BY
句内では、バインディングのキーワードAS
は、GROUP BY (?x + ?y AS ?z)
のように使用できます。これは{ ... BIND (?x + ?y AS ?z) } GROUP BY ?z
と同等です。
例えば、ソリューション・シーケンスS({?x→2, ?y→3}, {?x→2, ?y→5}, {?x→6, ?y→7})の場合、?xという値でソリューションをグループ化したいと思うかもしれませんし、グループごとに?yという値の平均を計算したいと思うかもしれません。
これは、次のように書くことができます。
SELECT (AVG(?y) AS ?avg) WHERE { ?a :x ?x ; :y ?y . } GROUP BY ?x
FILTER
がグループ化されていないソリューション集合で機能するのと同じように、HAVING
はグループ化されたソリューション集合で機能します。
次の項で述べているように、HAVING
式にはグループ化されたクエリからの射影と同じ評価規則があります。
HAVING
の使用の一例を、以下で示しています。
PREFIX : <http://data.example/> SELECT (AVG(?size) AS ?asize) WHERE { ?x :size ?size } GROUP BY ?x HAVING(AVG(?size) > 10)
これは、主語でグループ化されて、平均サイズを返すでしょうが、それは、平均サイズが10より大きい場合のみです。
集約を用いたクエリ・レベルでは、1つの例外を除き、集約と定数で構成される式のみを射影できます。GROUP BY
が、1つの変数のみで構成される1つ以上の単純式とともに与えられれば、それらの変数はレベルから射影できます。
例えば、?xがGROUP BY
用語として与えられた場合、次のクエリは正当です。
PREFIX : <http://example.com/data/#> SELECT ?x (MIN(?y) * 2 AS ?min) WHERE { ?x :p ?y . ?x :q ?z . } GROUP BY ?x (STR(?z))
これは単純変数式でないため、STR(?z)
を射影することが正当ではないだろうということに注意してください。しかし、GROUP BY (STR(?z) AS ?strZ)
の場合、?strZ
に射影できるでしょう。
GROUP BY
変数を用いていない他の式や集約は、SAMPLE
集約を用いて、それらのグループから非確定的な値を射影できます。
この項では、集約を用いたクエリの例を示し、集約が存在する場合に、結果においてエラーがどのように扱われるかを例示します。
データ:
@prefix : <http://example.com/data/#> . :x :p 1, 2, 3, 4 . :y :p 1, _:b2, 3, 4 .:z :p 1.0, 2.0, 3.0, 4 .
クエリ:
PREFIX : <http://example.com/data/#> SELECT ?g (AVG(?p) AS ?avg) ((MIN(?p) + MAX(?p)) / 2 AS ?c) WHERE { ?g :p ?p . } GROUP BY ?g
結果:
g | avg | c |
---|---|---|
<http://example.com/data/#x> | 2.5 | 2.5 |
<http://example.com/data/#y> | ||
<http://example.com/data/#z> | 2.5 | 2.5 |
:yグループのバインディングがAvg({1, _:b2, 3, 4})の評価として結果に含まれておらず、(_:b2 + 4) / 2はエラーで、ソリューションからバインディングが削除されることに注意してください。
サブクエリは通常、クエリ内の部分式の結果の数を制限するなど、他の方法では得られない結果を得るために、SPARQLクエリを他のクエリに組み込む方法です。
SPARQLクエリの評価にはボトム・アップの性質があるため、必然的にサブクエリが最初に評価され、その結果が外部のクエリに射影されます。
外部のクエリには、サブクエリから射影された変数のみが見える(または、範囲内である)ことに注意してください。
データ:
@prefix : <http://people.example/> . :alice :name "Alice", "Alice Foo", "A. Foo" . :alice :knows :bob, :carol . :bob :name "Bob", "Bob Bar", "B. Bar" . :carol :name "Carol", "Carol Baz", "C. Baz" .
アリスを知っており、名前を持っているすべての人に関し、名前(ソート順序が最下位もの)を返します。
クエリ:
PREFIX : <http://people.example/> PREFIX : <http://people.example/> SELECT ?y ?minName WHERE { :alice :knows ?y . { SELECT ?y (MIN(?name) AS ?minName) WHERE { ?y :name ?name . } GROUP BY ?y } }
結果:
y | minName |
---|---|
:bob | "B. Bar" |
:carol | "C. Baz" |
この結果は、最初に内部クエリを評価することで得られます。
SELECT ?y (MIN(?name) AS ?minName) WHERE { ?y :name ?name . } GROUP BY ?y
これにより、次のソリューション・シーケンスが生成されます。
y | minName |
---|---|
:alice | "A. Foo" |
:bob | "B. Bar" |
:carol | "C. Baz" |
これは、次のように、外部クエリの結果と結合されます。
y |
---|
:bob |
:carol |
RDFデータ・モデルは、主語、述語、目的語のトリプルから成るグラフとして情報を表します。多くのRDFデータを蓄積すると、複数のRDFグラフと各グラフに関する記録情報が保持され、それによって、アプリケーションは1つ以上のグラフの情報を含むクエリを作成できます。
SPARQLのクエリは、グラフのコレクションを表すRDFデータセットに対して実行されます。1つのRDFデータセットは、名前のない1つのグラフ(デフォルト・グラフ)と、名前付きグラフがそれぞれにIRIで識別される0以上の名前付きグラフから成ります。SPARQLのクエリは、13.3 データセットのクエリの項で述べるように、クエリ・パターンの異なる部分を異なるグラフに対してマッチさせることができます。
RDFデータセットには、0の名前付きグラフを含むことができます。RDFデータセットには、常に1つのデフォルト・グラフが含まれます。クエリは、デフォルト・グラフのマッチングを含る必要はありません。クエリは、名前付きグラフのマッチングを含むことができるだけです。
基本グラフ・パターンをマッチングさせるために用いるグラフは、アクティブ・グラフです。前項までは、すべてのクエリは、アクティブ・グラフとしてのRDFデータセットのデフォルト・グラフである、1つのグラフに対して実行したものを示してきました。GRAPH
キーワードは、アクティブ・グラフを、クエリの一部に対するデータセット内のすべての名前付きグラフのうちの1つにするために用いられます。
RDFデータセットの定義は、名前付きグラフとデフォルト・グラフの関係を制限しません。異なるグラフで情報を繰り返すことができ、グラフ間の関係を公開できます。次の2つの有益な処理があります。
# Default graph @prefix dc: <http://purl.org/dc/elements/1.1/> . <http://example.org/bob> dc:publisher "Bob" . <http://example.org/alice> dc:publisher "Alice" .
# Named graph: http://example.org/bob @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Bob" . _:a foaf:mbox <mailto:[email protected]> .
# Named graph: http://example.org/alice @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> .
この例では、デフォルト・グラフには、2つの名前付きグラフの公開者名が含まれています。名前付きグラフのトリプルは、この例のデフォルト・グラフでは表示されません。
例2:
RDFデータは、グラフのRDFマージ[RDF-MT]によって組み合わすことができます。RDFデータセットにおける、グラフの1つの可能な処理は、デフォルト・グラフを名前付きグラフの情報の一部またはすべてのRDFマージにすることです。
次の例では、名前付きグラフには、以前と同じトリプルが含まれています。RDFデータセットは、デフォルト・グラフに名前付きグラフのRDFマージを含んでおり、再ラベル付けを行って空白ノードを異なったものにしておきます。
# Default graph @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:x foaf:name "Bob" . _:x foaf:mbox <mailto:[email protected]> . _:y foaf:name "Alice" . _:y foaf:mbox <mailto:[email protected]> .
# Named graph: http://example.org/bob @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Bob" . _:a foaf:mbox <mailto:[email protected]> .
# Named graph: http://example.org/alice @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> .
RDFマージでは、マージされたグラフの空白ノードと、マージされているグラフからの空白ノードとは共有されません。
SPARQLクエリは、RDFデータセットを記述するために、FROM
句とFROM NAMED
句を用いて、マッチングに用いるデータセットを指定できます。クエリがそのようなデータセットの記述を提供していれば、それは、データセットの記述がクエリで提供されない場合にクエリ・サービスが使用する任意のデータセットの代わりに使用しています。また、RDFデータセットは、SPARQLプロトコル要求で指定することもできます。その場合、プロトコルの記述により、クエリ自体のあらゆる記述は無効になります。クエリ・サービスがデータセットの記述を許容できない場合には、サービスはクエリ要求を拒否するかもしれません。
FROM
とFROM NAMED
キーワードによって、クエリは参照によってRDFデータセットを指定できます。これは、データセットが、与えられたIRI(すなわち、与えられたIRI参照の絶対形式)によって識別された資源の表現から得られるグラフを含むべきであるということを示しています。いくつかのFROM
とFROM NAMED
句から生じるデータセットは次の通りです。
FROM
句で参照されたグラフのRDFマージから成るデフォルト・グラフ、およびFROM NAMED
句から1つずつ。FROM
句はないけれども複数のFROM NAMED
句がある場合は、データセットにはデフォルト・グラフに対する空のグラフが含まれています。
各FROM
句には、デフォルト・グラフを作成するために用いるグラフを示すIRIが含まれています。これは、グラフを名前付きグラフとして位置づけるものではありません。
この例では、RDFデータセットは、1つのデフォルト・グラフを含み、名前付きグラフを含んでいません。
# Default graph (located at http://example.org/foaf/aliceFoaf) @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> .
クエリが1つ以上のFROM
句を提供し、デフォルト・グラフを示すために1つ以上のIRIを提供する場合、デフォルト・グラフは与えられたIRIによって識別される資源の表現から得られたグラフのRDFマージです。
FROM NAMED
句を用いれば、クエリは、RDFデータセットの名前付きグラフにIRIを提供できます。各IRIは、RDFデータセットの1つの名前付きグラフを提供するために用いられます。2つ以上のFROM NAMED
句で同じIRIを用いると、データセットに現れる当該IRIを持つ1つの名前付きグラフになります。
# Graph: http://example.org/bob @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Bob" . _:a foaf:mbox <mailto:[email protected]> .
# Graph: http://example.org/alice @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> .
... FROM NAMED <http://example.org/alice> FROM NAMED <http://example.org/bob> ...
FROM NAMED
構文は、IRIが対応するグラフを識別するということを示唆しますが、RDFデータセットのIRIとグラフとの関係は間接的です。IRIが資源を識別し、資源はグラフで(あるいは、より正確には、グラフをシリアル化したドキュメントで)表されます。詳細については[WEBARCH]を参照してください。
FROM
句とFROM NAMED
句は、同じクエリ内で使用できます。
# Default graph (located at http://example.org/dft.ttl) @prefix dc: <http://purl.org/dc/elements/1.1/> . <http://example.org/bob> dc:publisher "Bob Hacker" . <http://example.org/alice> dc:publisher "Alice Hacker" .
# Named graph: http://example.org/bob @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Bob" . _:a foaf:mbox <mailto:[email protected]> .
# Named graph: http://example.org/alice @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?who ?g ?mbox FROM <http://example.org/dft.ttl> FROM NAMED <http://example.org/alice> FROM NAMED <http://example.org/bob> WHERE { ?g dc:publisher ?who . GRAPH ?g { ?x foaf:mbox ?mbox } }
このクエリに対するRDFデータセットには、1つのデフォルト・グラフと2つの名前付きグラフが含まれています。GRAPH
キーワードに関しては、以下で説明しています。
データセットを構築するために必要なアクションは、データセットの記述のみでは決められません。2つのFROM
句、または、1つのFROM
句と1つのFROM NAMED
句を用いてデータセットの記述にIRIが2度付与されている場合は、きっかり1回または、きっかり2回の試みでIRIに関連付けられた1つのRDFグラフを得たとは想定しません。したがって、データセットの記述に存在する2つから得られたトリプル中の空白ノードのアイデンティティに関する想定を行えません。概して、グラフの同等性に関する想定を行えません。
グラフのコレクションにクエリを実行する際には、GRAPH
キーワードを用いて、名前付きグラフに対してパターンをマッチングさせます。GRAPH
は、IRIを提供して1つのグラフを選択するか、クエリのRDFデータセット内のすべての名前付きグラフのIRIの範囲をカバーする変数を使用できます。
GRAPH
を用いれば、クエリのその一部でグラフ・パターンをマッチングさせるためのアクティブ・グラフが変更されます。GRAPH
を用いない場合は、マッチングは、デフォルトのグラフを用いて行われます。
以下の例では、次の2つのグラフを用います。
# Named graph: http://example.org/foaf/aliceFoaf @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> . _:a foaf:knows _:b . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> . _:b foaf:nick "Bobby" . _:b rdfs:seeAlso <http://example.org/foaf/bobFoaf> . <http://example.org/foaf/bobFoaf> rdf:type foaf:PersonalProfileDocument .
# Named graph: http://example.org/foaf/bobFoaf @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . _:z foaf:mbox <mailto:[email protected]> . _:z rdfs:seeAlso <http://example.org/foaf/bobFoaf> . _:z foaf:nick "Robert" . <http://example.org/foaf/bobFoaf> rdf:type foaf:PersonalProfileDocument .
次のクエリは、データセットの各名前付きグラフにグラフ・パターンをマッチングさせ、マッチしたグラフのIRIにバインドされたsrc
変数を持つソリューションを作成します。グラフ・パターンは、データセットの各名前付きグラフであるアクティブ・グラフとマッチします。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?src ?bobNick FROM NAMED <http://example.org/foaf/aliceFoaf> FROM NAMED <http://example.org/foaf/bobFoaf> WHERE { GRAPH ?src { ?x foaf:mbox <mailto:[email protected]> . ?x foaf:nick ?bobNick } }
クエリの結果は、情報が発見されたグラフの名前と、Bobのnickの値を提示します。
クエリは、グラフIRIの提供により、特定のグラフに適用されたマッチングを制限できます。これは、IRIで名前付けされたグラフに、アクティブ・グラフを設定します。このクエリは、グラフ http://example.org/foaf/bobFoaf
で示されているように、Bobのnickを検索します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX data: <http://example.org/foaf/> SELECT ?nick FROM NAMED <http://example.org/foaf/aliceFoaf> FROM NAMED <http://example.org/foaf/bobFoaf> WHERE { GRAPH data:bobFoaf { ?x foaf:mbox <mailto:[email protected]> . ?x foaf:nick ?nick } }
これにより、次の1つのソリューションが得られます。
GRAPH
句で用いられる変数は、もう1つのGRAPH
句、または、データセットのデフォルト・グラフにマッチしたグラフ・パターンでも使用できます。
次のクエリは、Bobのプロフィール・ドキュメントを発見するためにIRI http://example.org/foaf/aliceFoaf
を持つグラフを用いており、そのグラフに別のパターンをマッチさせます。AliceのFOAFファイルからファイルの変数whom
にマッチングさせるため用いられる空白ノードは、プロフィール・ドキュメントの空白ノードと同じではないため(異なるグラフに存在する)、2番目のGRAPH
句のパターンは、最初のGRAPH
句(変数whom
)で発見されたのと同じメールボックス(変数mbox
によって示される)を持つ人の空白ノード(変数w
)を発見します。
PREFIX data: <http://example.org/foaf/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?mbox ?nick ?ppd FROM NAMED <http://example.org/foaf/aliceFoaf> FROM NAMED <http://example.org/foaf/bobFoaf> WHERE { GRAPH data:aliceFoaf { ?alice foaf:mbox <mailto:[email protected]> ; foaf:knows ?whom . ?whom foaf:mbox ?mbox ; rdfs:seeAlso ?ppd . ?ppd a foaf:PersonalProfileDocument . } . GRAPH ?ppd { ?w foaf:mbox ?mbox ; foaf:nick ?nick } }
mbox | nick | ppd |
---|---|---|
<mailto:[email protected]> | "Robert" | <http://example.org/foaf/bobFoaf> |
変数nick
を含むパターンがppd
によって特定のパーソナル・プロフィール・ドキュメントに制限されているため、Bobのnick
を示しているAliceのFOAFファイルのトリプルは、Bobにnickを提供するために用いられていません。
クエリ・パターンは、デフォルト・グラフと名前付グラフの両方を含むことができます。この例では、アグリゲータは、2回の別の機会に1つのウェブ資源を読み込みました。グラフには、アグリゲータに読み込まれるたびに、ローカル・システムによってIRIが与えられます。これらのグラフはほぼ同じですが、「Bob」のEメール・アドレスが変更されました。
この例では、デフォルト・グラフは、来歴情報を記録するために用いられており、実際に読み込まれたRDFデータは2つの別々のグラフに保持され、システムはそれぞれに異なるIRIを与えます。RDFデータセットは、2つの名前付きグラフとそれらに関する情報で構成されます。
RDFデータセット:
# Default graph @prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix g: <tag:example.org,2005-06-06:> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . g:graph1 dc:publisher "Bob" . g:graph1 dc:date "2004-12-06"^^xsd:date . g:graph2 dc:publisher "Bob" . g:graph2 dc:date "2005-01-10"^^xsd:date .
# Graph: locally allocated IRI: tag:example.org,2005-06-06:graph1 @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> .
# Graph: locally allocated IRI: tag:example.org,2005-06-06:graph2 @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> .
このクエリは、Eメール・アドレスを発見し、人名と情報が発見された日時を詳細化します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?name ?mbox ?date WHERE { ?g dc:publisher ?name ; dc:date ?date . GRAPH ?g { ?person foaf:name ?name ; foaf:mbox ?mbox } }
結果は、「Bob」のEメール・アドレスが変更されたことを示します。
name | mbox | date |
---|---|---|
"Bob" | <mailto:[email protected]> | "2004-12-06"^^xsd:date |
"Bob" | <mailto:[email protected]> | "2005-01-10"^^xsd:date |
クエリ・パターンは、各ソリューションが変数からRDF用語への部分関数である、順不同のソリューションのコレクションを作成します。次に、これらのソリューションは、シーケンス(ソリューション・シーケンス)として処理されます。最初は特に順序付けのないシーケンスで、後で、任意のシーケンス修飾子を適用して別のシーケンスを作成します。最終的に、この後者のシーケンスを用いて、SPARQLクエリ形式の結果の1つを生成します。
ソリューション・シーケンス修飾子は、次のいずれか1つです。
修飾子は、上記リストで示されている順序で適用されます。
ORDER BY
句は、ソリューション・シーケンスの順序を定めます。
ORDER BY
句の後には、式と、オプションの順序修飾子(ASC()
かDESC()
のどちらか)で構成された順序コンパレータ(order comparator)のシーケンスが続きます。各順序付けコンパレータは、昇順(ASC()
修飾子、または、修飾子なしで示される)か、降順(DESC()
修飾子で示される)です。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name WHERE { ?x foaf:name ?name } ORDER BY ?name
PREFIX : <http://example.org/ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name WHERE { ?x foaf:name ?name ; :empId ?emp } ORDER BY DESC(?emp)
PREFIX : <http://example.org/ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name WHERE { ?x foaf:name ?name ; :empId ?emp } ORDER BY ?name DESC(?emp)
「<」という演算子(演算子マッピングおよび17.3.1 演算子の拡張性を参照)は、数値(numerics
)、シンプルなリテラル(simple literals
)、xsd:strings
、xsd:booleans
、xsd:dateTimes
の対の相対順序を定めます。IRIの対は、simple literals
として比較し、順序付けられます。
SPARQLは、次の、別の方法では順序付けられない数種のRDF用語間の順序も定めます。
プレーン・リテラルは、同じ字句形式の型xsd:string
を持つRDFリテラルよりも順序が低いです。
SPARQLは、可能な限りのあらゆるRDF用語の全体的な順序付けを定めるわけではありません。以下は、相対順序が定められていない対の用語のいくつかの例です。
この変数バインディングのリストは、昇順です。
RDF Term | Reason |
---|---|
Unbound results sort earliest. | |
_:z |
Blank nodes follow unbound. |
_:a |
There is no relative ordering of blank nodes. |
<http://script.example/Latin> |
IRIs follow blank nodes. |
<http://script.example/Кириллица> |
The character in the 23rd position, "К", has a unicode codepoint 0x41A, which is higher than 0x4C ("L"). |
<http://script.example/漢字> |
The character in the 23rd position, "漢", has a unicode codepoint 0x6F22, which is higher than 0x41A ("К"). |
"http://script.example/Latin" |
Simple literals follow IRIs. |
"http://script.example/Latin"^^xsd:string |
xsd:strings follow simple literals. |
順序付けコンパレータに対する2つのソリューションの昇順は、ソリューションのバインディングを式に代入し、それを「<」演算子で比較することで定めることができます。降順は昇順の逆です。
2つのソリューションの相対順序は、シーケンス内の最初の順序付けコンパレータに対する2つのソリューションの相対順序です。ソリューション・バインディングの置換が同じRDF用語を作成するソリューションの場合は、順序は次の順序付けコンパレータに対する2つのソリューションの相対順序です。2つのソリューションに対して評価が行われた順序の式が別々のRDF用語を作成しない場合、2つのソリューションの相対順序は未定義です。
ソリューションのシーケンスの順序付けは、常に、その内部に同数のソリューションを持つシーケンスになります。
ソリューション・シーケンスでCONSTRUCT
またはDESCRIBE
クエリに対しORDER BY
を使用すると、SELECT
のみが結果のシーケンスを返すため、直接的な効果はありません。LIMIT
やOFFSET
と組み合わせて用いれば、ORDER BY
は、ソリューション・シーケンスの異なる部分から生じる結果を返すために使用できます。ASK
クエリは、ORDER BY
、LIMIT
、または、OFFSET
を含みません。
ソリューション・シーケンスは変数のサブセットのみを含むものに変換できます。シーケンスの各ソリューションに対し、SELECTクエリ形式を用いて変数の指定選択を用いることで新しいソリューションが作成されます。
以下の例では、FOAFプロパティーを用いて、RDFグラフで記述された人名のみを抽出するためのクエリを示しています。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name WHERE { ?x foaf:name ?name }
name |
---|
"Bob" |
"Alice" |
DISTINCT
またはREDUCED
というクエリ修飾子を用いないソリューション・シーケンスは、複製のソリューションを保持するでしょう。
データ:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:x foaf:name "Alice" . _:x foaf:mbox <mailto:[email protected]> . _:y foaf:name "Alice" . _:y foaf:mbox <mailto:[email protected]> . _:z foaf:name "Alice" . _:z foaf:mbox <mailto:[email protected]> .
クエリ:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name WHERE { ?x foaf:name ?name }
結果:
name |
---|
"Alice" |
"Alice" |
"Alice" |
DISTINCT
およびREDUCED
の修飾子は、クエリの結果に重複が含まれるかどうかに影響を与えます。
DISTINCT
ソリューション修飾子は、重複するソリューションを排除します。同じ変数を同じRDF用語にバインドする1つのソリューションのみが、クエリから返されます。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT DISTINCT ?name WHERE { ?x foaf:name ?name }
name |
---|
"Alice" |
ソリューション・シーケンス修飾子の順序にあるように、limitかoffsetのいずれかが適用される前に重複が排除されることに注意してください。
DISTINCT
修飾子は、ソリューション集合から重複したソリューションを確実に排除しますが、REDUCED
は、単にそれらを排除することを許可するだけです。REDUCED
ソリューション集合の変数バインディング集合のカーディナリティーは、少なくとも1で、多くともDISTINCT
またはREDUCED
修飾子を用いないソリューション集合のカーディナリティーを超えません。例えば、上記のデータを用いた場合、次のクエリは、
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT REDUCED ?name WHERE { ?x foaf:name ?name }
1、2(ここで示しているもの)、または、3つのソリューションを持つことができます。
name |
---|
"Alice" |
"Alice" |
SPARQLには、4つのクエリ形式があります。これらのクエリ形式は、パターン・マッチングのソリューションを用いて、結果集合またはRDFグラフを作成します。クエリ形式は、次の通りです。
SELECT
クエリからの結果集合、または、ASK
クエリのブール演算結果をシリアル化するためにSPARQL 1.1クエリ結果JSONフォーマット、SPARQLクエリ結果XMLフォーマット、SPARQL 1.1クエリ結果CSVおよびTSVフォーマットなどのフォーマットを使用できます。
結果のSELECT形式は、変数とそのバインディングを直接返します。これは、必須の変数を射影するオペレーションと、新しい変数バインディングのクエリ・ソリューションへの導入とを組み合わせます。
変数名のリストがSELECT句で与えられれば、特定の変数とそのバインディングが返されます。SELECT *
という構文は、クエリ中のその時点で範囲内にある変数をすべて選択するための省略形です。これは、MINUS
の右側のFILTER
でのみ使用されている変数を除外し、サブクエリを対象に入れます。
SELECT *
の使用は、クエリにGROUP BY
句がない場合にのみ認められています。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:knows _:b . _:a foaf:knows _:c . _:b foaf:name "Bob" . _:c foaf:name "Clare" . _:c foaf:nick "CT" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?nameX ?nameY ?nickY WHERE { ?x foaf:knows ?y ; foaf:name ?nameX . ?y foaf:name ?nameY . OPTIONAL { ?y foaf:nick ?nickY } }
結果集合は、ローカルAPIからアクセスできますが、JSON、XML、CSV、TSVのいずれかにシリアル化することも可能です。
{ "head": { "vars": [ "nameX" , "nameY" , "nickY" ] } , "results": { "bindings": [ { "nameX": { "type": "literal" , "value": "Alice" } , "nameY": { "type": "literal" , "value": "Bob" } } , { "nameX": { "type": "literal" , "value": "Alice" } , "nameY": { "type": "literal" , "value": "Clare" } , "nickY": { "type": "literal" , "value": "CT" } } ] } }
<?xml version="1.0"?> <sparql xmlns="http://www.w3.org/2005/sparql-results#"> <head> <variable name="nameX"/> <variable name="nameY"/> <variable name="nickY"/> </head> <results> <result> <binding name="nameX"> <literal>Alice</literal> </binding> <binding name="nameY"> <literal>Bob</literal> </binding> </result> <result> <binding name="nameX"> <literal>Alice</literal> </binding> <binding name="nameY"> <literal>Clare</literal> </binding> <binding name="nickY"> <literal>CT</literal> </binding> </result> </results> </sparql>
SELECT句は、パターン・マッチングのどの変数を結果に含むかの選定に加え、新しい変数の導入も行えます。SELECT式の割り当て規則は、BINDの割り当てと同じです。この式は、クエリ・ソリューションに既にある変数バインディング、または、SELECT句で以前に定義された変数バインディングを組み合わせて、クエリ・ソリューション内にバインディングを生成します。
(expr AS v)
のスコーピングは、即座に適用されます。SELECT
式では、変数は、後で同じSELECT句内の式で使用できますが、同じSELECT
句内で再度指定することはできません。
例:
データ:
@prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix : <http://example.org/book/> . @prefix ns: <http://example.org/ns#> . :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book1 ns:discount 0.2 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 . :book2 ns:discount 0.25 .
クエリ:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX ns: <http://example.org/ns#> SELECT ?title (?p*(1-?discount) AS ?price) { ?x ns:price ?p . ?x dc:title ?title . ?x ns:discount ?discount }
結果:
title | price |
---|---|
"The Semantic Web" | 17.25 |
"SPARQL Tutorial" | 33.6 |
新しい変数は、構文上、それが同じSELECT句内で以前に導入されていれば、式でも使用できます。
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX ns: <http://example.org/ns#> SELECT ?title (?p AS ?fullPrice) (?fullPrice*(1-?discount) AS ?customerPrice) { ?x ns:price ?p . ?x dc:title ?title . ?x ns:discount ?discount }
結果:
title | fullPrice | customerPrice |
---|---|---|
"The Semantic Web" | 23 | 17.25 |
"SPARQL Tutorial" | 42 | 33.6 |
CONSTRUCT
クエリ形式は、グラフ・テンプレートで指定された1つのRDFグラフを返します。結果は、各クエリのソリューションをソリューション・シーケンスに取り込み、グラフ・テンプレートに変数を代入し、和集合によってトリプルを1つのRDFグラフに結合して作成されたRDFグラフです。
このようなインスタンス化が、主語または述語の位置にあるリテラルなどの、バインドされていない変数または不正なRDF構成子を含むトリプルを作成する場合は、そのトリプルは出力RDFグラフに含まれません。グラフ・テンプレートは、変数を持たないトリプル(基底的または明示的なトリプルとして知られる)を含むことができ、これらはCONSTRUCTクエリ形式が返した出力RDFグラフにも表示されます。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:[email protected]> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> CONSTRUCT { <http://example.org/person#Alice> vcard:FN ?name } WHERE { ?x foaf:name ?name }
は、FOAF情報からvcardプロパティーを作成します。
@prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> . <http://example.org/person#Alice> vcard:FN "Alice" .
テンプレートは、空白ノードを含んだRDFグラフを作成できます。空白ノード・ラベルは、各ソリューションに対するテンプレートで有効です。同じラベルが1つのテンプレートで2回出現する場合は、各クエリ・ソリューションに対して作成された1つの空白ノードが存在するでしょうが、別のクエリ・ソリューションによって生成されたトリプルに対する別の空白ノードが存在するでしょう。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:givenname "Alice" . _:a foaf:family_name "Hacker" . _:b foaf:firstname "Bob" . _:b foaf:surname "Hacker" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> CONSTRUCT { ?x vcard:N _:v . _:v vcard:givenName ?gname . _:v vcard:familyName ?fname } WHERE { { ?x foaf:firstname ?gname } UNION { ?x foaf:givenname ?gname } . { ?x foaf:surname ?fname } UNION { ?x foaf:family_name ?fname } . }
は、FOAF情報に対応するvcardプロパティーを作成します。
@prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> . _:v1 vcard:N _:x . _:x vcard:givenName "Alice" . _:x vcard:familyName "Hacker" . _:v2 vcard:N _:z . _:z vcard:givenName "Bob" . _:z vcard:familyName "Hacker" .
テンプレートで変数x
を用いると(この例では、データ内でラベル_:a
と_:b
を持つ空白ノードにバインドされているでしょう)、結果として生成されるRDFグラフの中に別の空白ノード・ラベル(_:v1
と_:v2
)が生成されます。
CONSTRUCT
を用いて、ターゲットのRDFデータセットからグラフの部分または全体を抽出することが可能です。この最初の例は、IRIラベルhttp://example.org/aGraph
を持つグラフ(それがデータセットにあれば)を返します。さもなければ、空のグラフを返します。
CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <http://example.org/aGraph> { ?s ?p ?o } . }
グラフへのアクセスは、他の情報を条件としている場合があります。例えば、デフォルト・グラフがデータセットの名前付きグラフに関するメタデータを含んでいる場合、次のようなクエリは、名前付きグラフに関する情報に基づく1つのグラフを抽出できます。
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX app: <http://example.org/ns#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> CONSTRUCT { ?s ?p ?o } WHERE { GRAPH ?g { ?s ?p ?o } . ?g dc:publisher <http://www.w3.org/> . ?g dc:date ?date . FILTER ( app:customDate(?date) > "2005-02-28T00:00:00Z"^^xsd:dateTime ) . }
ここでは、app:customDate
が拡張関数を識別し、日付フォーマットをxsd:dateTime
というRDF用語に変えました。
クエリのソリューション修飾子は、CONSTRUCT
クエリの結果に影響を与えます。この例では、CONSTRUCT
テンプレートからの出力グラフは、グラフ・パターン・マッチング2つのソリューションのみから形成されます。クエリは、ヒット率で格付けされたトップ2のサイトを持つ人々の名前を持つグラフを出力します。RDFグラフ中のトリプルは順序付けされていません。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix site: <http://example.org/stats#> . _:a foaf:name "Alice" . _:a site:hits 2349 . _:b foaf:name "Bob" . _:b site:hits 105 . _:c foaf:name "Eve" . _:c site:hits 181 .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX site: <http://example.org/stats#> CONSTRUCT { [] foaf:name ?name } WHERE { [] foaf:name ?name ; site:hits ?hits . } ORDER BY desc(?hits) LIMIT 2
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:x foaf:name "Alice" . _:y foaf:name "Eve" .
CONSTRUCTクエリ形式の省略形は、テンプレートとパターンが同じである場合や、パターンが単なる基本グラフ・パターンである場合に提供されます(FILTER
および複雑なグラフ・パターンは、省略形が認められていません)。省略形では、キーワードWHERE
は必須です。
次の2つのクエリは同じで、最初のクエリは2番目クエリの省略形です。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT WHERE { ?x foaf:name ?name }
PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?x foaf:name ?name } WHERE { ?x foaf:name ?name }
アプリケーションは、クエリ・パターンにソリューションがあるか否かをテストするためにASK
形式を使用できます。ありえるクエリのソリューションに関する情報は返さず、ソリューションが存在しているか否かのみです。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice" . _:a foaf:homepage <http://work.example.org/alice/> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> ASK { ?x foaf:name "Alice" }
true
この結果集合のSPARQLクエリ結果XMLフォーマットの形式は、次のようになります。
<?xml version="1.0"?> <sparql xmlns="http://www.w3.org/2005/sparql-results#"> <head></head> <boolean>true</boolean> </sparql>
同じデータを用いた場合、次の例は、Aliceのmbox
が記述されていないため、マッチを返しません。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> ASK { ?x foaf:name "Alice" ; foaf:mbox <mailto:[email protected]> }
false
DESCRIBE
形式は、資源に関するRDFデータを含んだ1つの結果RDFグラフを返します。SPARQLのクエリではこのデータは規定されておらず、この場合には、クエリのクライアントがデータ情報源内のRDFの構造を知っている必要があるでしょうが、その代わりにSPARQLクエリ・プロセッサがこのデータを決定します。クエリ・パターンを用いて結果集合を作成します。DESCRIBE
形式は、IRIで直接指定された任意の資源と一緒に、識別された各資源をソリューションに取り込み、ターゲットのRDFデータセットを含んでいる利用可能な任意の情報から得られる「記述」を持ってくることによって、1つのRDFグラフを組み立てます。記述はクエリ・サービスが決定します。DESCRIBE *
という構文は、クエリ内のすべての変数を記述するための省略形です。
DESCRIBE
句自身がIRIを取り込んで資源を識別することができます。最もシンプルなDESCRIBE
クエリは、次のようなDESCRIBE
句内にIRIのみがあるものです。
DESCRIBE <http://example.org/>
記述される資源は、クエリ変数へのバインディングから結果集合に取り込むこともできます。これによって、次のような、資源がIRIによって識別されるのか、データセットの空白ノードによって識別されるのかの記述が可能になります。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> DESCRIBE ?x WHERE { ?x foaf:mbox <mailto:alice@org> }
プロパティーfoaf:mbox
は、FOAF語彙では、逆関数型プロパティーであると定義されています。そういうものとして処理すると、このクエリは、高々1人の人物に関する情報を返すでしょう。しかし、クエリ・パターンに複数のソリューションがある場合は、それぞれに対するRDFデータは、すべてのRDFグラフ記述の和集合です。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> DESCRIBE ?x WHERE { ?x foaf:name "Alice" }
次のように、1つ以上のIRIまたは変数を作成できます。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> DESCRIBE ?x ?y <http://example.org/> WHERE {?x foaf:knows ?y}
返されるRDFは、情報の発行者が決定します。これは、サービスが、記述されている資源に関するものと見なす情報かもしれません。他の資源に関する情報を含むことができます。例えば、本のRDFデータには、著者に関する詳細を含むこともできます。
次のようなシンプルなクエリは、
PREFIX ent: <http://org.example.com/employees#> DESCRIBE ?x WHERE { ?x ent:employeeId "1234" }
下記のような、従業員の記述や、何らかの他の潜在的に役に立つ詳細情報を返すかもしれません。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0> . @prefix exOrg: <http://org.example.com/employees#> . @prefixrdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix owl: <http://www.w3.org/2002/07/owl#>
_:a exOrg:employeeId "1234" ;foaf:mbox_sha1sum "bee135d3af1e418104bc42904596fe148e90f033" ;
vcard:N [ vcard:Family "Smith" ; vcard:Given "John" ] .foaf:mbox_sha1sum rdf:type owl:InverseFunctionalProperty .
これには、vcard語彙vcard:Nに対する空白ノード・クロージャが含まれいます。どのような情報を返すかを決定できる他のメカニズムには、Concise Bounded Descriptions[CBD]などもあります。
WHERE
FOAFなどの語彙では、通常は、資源は空白ノードであるため、InverseFunctionalPropertyであるfoaf:mbox_sha1sum
などのノードを識別するのに十分な情報や、名前やその他の詳細データといった情報を返すのが適切でしょう。例では、WHERE
句に対するマッチが返されましたが、これは必須ではありません。
SPARQLのFILTERs
は、与えられた制約に従ってグラフ・パターン・マッチのソリューションを制限します。具体的には、FILTERs
は、式に代入したときに、偽(false
)の有効なブール値になったり、エラーを起こしたりするソリューションを排除します。有効なブール値は17.2.2 有効なブール値の項で定義されており、エラーはXQuery1.0: XMLクエリ言語[XQUERY]の2.3.1, エラーの種類の項で定義されています。これらのエラーは、FILTER
の評価以外には影響を与えません。
RDFリテラルは、データ型IRIを持つことができます。
@prefix a: <http://www.w3.org/2000/10/annotation-ns#> . @prefix dc: <http://purl.org/dc/elements/1.1/> . _:a a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:a dc:date "2004-12-31T19:00:00-05:00" . _:b a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:b dc:date "2004-12-31T19:01:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
最初のdc:date
トリプルの目的語には、型情報が全くありません。2番目のものには、xsd:dateTime
というデータ型があります。
SPARQLの式は文法に従って構築され、関数(IRIによって名前が付けられる)と演算子関数へのアクセスを提供します(SPARQL文法のキーワードとシンボルで呼び出される)。SPARQLの演算子は、型付リテラルの値を比較するために使用できます。
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?annot WHERE { ?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . ?annot dc:date ?date . FILTER ( ?date > "2005-01-01T00:00:00Z"^^xsd:dateTime ) }
SPARQLの演算子は、17.3項に記載されており、文法上の生成規則に関連付けられています。
さらに、SPARQLは、17.5項に記載している、XPathキャスト関数のサブセットを含む、任意の関数を呼び出す能力を提供します。これらの関数は、名前(IRI)によってSPARQLクエリの中に呼び出されます。例えば次のとおりです。
... FILTER ( xsd:dateTime(?date) < xsd:dateTime("2005-01-01T00:00:00Z") ) ...
この項の表記上の規定: XPath演算子は接頭辞op:
でラベル付けされています。XPath演算子には名前空間がなく、op:
はラベル付け上の慣習です。
SPARQLの関数と演算子は、RDF用語とSPARQL変数を演算します。これらの関数および演算子のサブセットは、XQuery 1.0とXPath 2.0関数および演算子[FUNCOP]から持って来たもので、XMLスキーマ型付き値の引数を持っており、型を返します。これらの関数と演算子に引数として渡されたRDF型付きリテラル(typed literals
)は、字句形式(lexical form
)の文字列の値を持つXMLスキーマの型付き値と、データ型IRIに対応するアトミックなデータ型にマッピングされます。返された型付き値は、同様にRDFの型付きリテラル(typed literals
)にマッピングし返されます。
SPARQLには、RDF用語の特定のサブセットに基づいて演算する付加的な演算子があります。型について述べるときには、次の用語は、XMLスキーマ[XSDT]のデータ型IRIに対応する型付きリテラル(typed literal
)を表します。
次の用語は、SPARQL値テストに用いられる付加的な型を識別します。
xsd:integer
、xsd:decimal
、xsd:float
、および、xsd:double
を持つ型付きリテラル(typed literals
)を表します。language tag
)を持たないプレーン・リテラル(plain literal
)を表します。
IRI
、リテラル(literal
)、および、空白ノード(blank node
)の型を表します。次の型は、数値の型から得られ、数値引数を取る関数と演算子に対する有効な引数です。
xsd:nonPositiveInteger
xsd:negativeInteger
xsd:long
xsd:int
xsd:short
xsd:byte
xsd:nonNegativeInteger
xsd:unsignedLong
xsd:unsignedInt
xsd:unsignedShort
xsd:unsignedByte
xsd:positiveInteger
SPARQLの言語拡張は、付加的な型をXMLスキーマ・データ型から得られるものとして扱うことができます。
SPARQLは、XQuery演算子マッピングで定義された関数と演算子のサブセットを提供します。XQuery 1.0の2.2.3 式の処理の項では、XPath関数の呼び出しについて説明しています。次の規則は、XQueryとSPARQLのデータと実行モデルの違いを調整します。
xsd:boolean
に強制変換されます。||
)または論理AND(&&
)を除く任意の式は、エラーを起こすでしょう。真(T)、偽(F)、エラー(E)に対する論理ANDと論理ORの真理値表は次の通りです。
A | B | A || B | A && B |
---|---|---|---|
T | T | T | T |
T | F | T | F |
F | T | T | F |
F | F | F | F |
T | E | T | E |
E | T | T | E |
F | E | E | F |
E | F | E | F |
E | E | E | E |
SPARQLは、引数のリストに関数を呼び出すための構文を定義しています。特に断りのない限り、これらは、次の通りに呼び出されます。
これらのステップのどれかが失敗すれば、呼び出しはエラーを起こします。エラーの影響は、フィルタ評価で定義されています。
「関数形式」というものもあり、これは、個々の形式で指定されているとおりに、関数に対して異なる評価規則を持ちます。
有効なブール値は、論理AND、論理OR、およびfn:notの論理関数に対する引数を計算するために用いられ、また、FILTER
式の結果の評価も行います。
XQueryの有効なブール値の規則は、XPathのfn:booleanの定義に依存しています。以下の規則は、SPARQLのクエリに存在している引数の型に適用されたfn:boolean
の規則を反映しています。
xsd:boolean
または数値(numeric)である任意のリテラルのEBVは、字句形式がそのデータ型(例えば、"abc"^^xsd:integer)に対して偽である場合は、偽です。xsd:boolean
のデータ型を持つ型付きリテラルであり、有効な字句形式を持っている場合、EBVはその引数の値です。xsd:string
のデータ型を持つ型付きリテラルである場合、オペランド値に0の長さがあるならEBVは偽で、そうれなければEBVは真です。真(true
)のEBVは、xsd:boolean
のデータ型および「真」の字句値を持つ型付きリテラルとして表され、 偽(false)のEBVは、xsd:boolean
のデータ型および「偽」の字句値を持つ型付きリテラルとして表されます。
SPARQLの文法は、一連の演算子を識別し(例えば、&&、*、isIRI)、制約を構築するために用いられます。以下のテーブルは、これらのそれぞれの文法上の生成規則と、XQuery 1.0とXPath 2.0関数および演算子[FUNCOP]、または17.4項のSPARQL演算子のいずれかによって定義されている適切なオペランドおよび演算子関数とを関連付けます。一連のパラメータに対する演算子定義を選択する際には、最も明確なパラメータを持つ定義が適用されます。例えば、xsd:integer = xsd:signedInt
を評価する際には、2つのRDF用語を持つ=
に対する定義ではなく、2つの数値(numeric
)パラメータを持つ=
に対する定義が適用されます。表は、最も実行可能性のある候補が最も明確になるように配列されています。適切なオペランドなしに呼び出された演算子は、型エラーになります。
SPARQLは、XPathの数値型昇格(numeric type promotion)に対するスキームと、数値演算子への引数に対する部分型置換(subtype substitution)に従います。数値オペランド(xsd:integer
、xsd:decimal
、xsd:float
、xsd:double
、および数値型から得られた型)のXPath演算子マッピング規則は、SPARQL演算子にも適用されます(数値型昇格および部分型置換の定義に関しては、XMLパス言語(XPath)2.0[XPATH20]を参照してください)。演算子の一部は、入れ子にされた関数式、例えばfn:not(op:numeric-equal(A, B))
に関連しています。XPathの定義によって、fn:not
およびop:numeric-equal
は、引数がエラーである場合にはエラーを起こします。
fn:compare
の照合順序は、XPathで定義され、http://www.w3.org/2005/xpath-functions/collation/codepoint
で識別されます。この照合順序は、コードポイント値に基づく文字列の比較を可能にします。コードポイント文字列の同等性は、RDF用語の同等性でテストできます。
演算子 | 型(A) | 関数 | 結果の型 |
---|---|---|---|
XQuery単項演算子 | |||
! A | xsd:boolean (EBV) | fn:not(A) | xsd:boolean |
+ A | 数値 | op:numeric-unary-plus(A) | 数値 |
- A | 数値 | op:numeric-unary-minus(A) | 数値 |
演算子 | 型(A) | 型(B) | 関数 | 結果の型 |
---|---|---|---|---|
論理結合子 | ||||
A || B | xsd:boolean (EBV) | xsd:boolean (EBV) | logical-or(A, B) | xsd:boolean |
A && B | xsd:boolean (EBV) | xsd:boolean (EBV) | logical-and(A, B) | xsd:boolean |
XPathテスト | ||||
A = B | 数値 | 数値 | op:numeric-equal(A, B) | xsd:boolean |
A = B | シンプルなリテラル | シンプルなリテラル | op:numeric-equal(fn:compare(A, B), 0) | xsd:boolean |
A = B | xsd:string | xsd:string | op:numeric-equal(fn:compare(STR(A), STR(B)), 0) | xsd:boolean |
A = B | xsd:boolean | xsd:boolean | op:boolean-equal(A, B) | xsd:boolean |
A = B | xsd:dateTime | xsd:dateTime | op:dateTime-equal(A, B) | xsd:boolean |
A != B | 数値 | 数値 | fn:not(op:numeric-equal(A, B)) | xsd:boolean |
A != B | シンプルなリテラル | シンプルなリテラル | fn:not(op:numeric-equal(fn:compare(A, B), 0)) | xsd:boolean |
A != B | xsd:string | xsd:string | fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 0)) | xsd:boolean |
A != B | xsd:boolean | xsd:boolean | fn:not(op:boolean-equal(A, B)) | xsd:boolean |
A != B | xsd:dateTime | xsd:dateTime | fn:not(op:dateTime-equal(A, B)) | xsd:boolean |
A < B | 数値 | 数値 | op:numeric-less-than(A, B) | xsd:boolean |
A < B | シンプルなリテラル | シンプルなリテラル | op:numeric-equal(fn:compare(A, B), -1) | xsd:boolean |
A < B | xsd:string | xsd:string | op:numeric-equal(fn:compare(STR(A), STR(B)), -1) | xsd:boolean |
A < B | xsd:boolean | xsd:boolean | op:boolean-less-than(A, B) | xsd:boolean |
A < B | xsd:dateTime | xsd:dateTime | op:dateTime-less-than(A, B) | xsd:boolean |
A > B | 数値 | 数値 | op:numeric-greater-than(A, B) | xsd:boolean |
A > B | シンプルなリテラル | シンプルなリテラル | op:numeric-equal(fn:compare(A, B), 1) | xsd:boolean |
A > B | xsd:string | xsd:string | op:numeric-equal(fn:compare(STR(A), STR(B)), 1) | xsd:boolean |
A > B | xsd:boolean | xsd:boolean | op:boolean-greater-than(A, B) | xsd:boolean |
A > B | xsd:dateTime | xsd:dateTime | op:dateTime-greater-than(A, B) | xsd:boolean |
A <= B | 数値 | 数値 | logical-or(op:numeric-less-than(A, B), op:numeric-equal(A, B)) | xsd:boolean |
A <= B | シンプルなリテラル | シンプルなリテラル | fn:not(op:numeric-equal(fn:compare(A, B), 1)) | xsd:boolean |
A <= B | xsd:string | xsd:string | fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 1)) | xsd:boolean |
A <= B | xsd:boolean | xsd:boolean | fn:not(op:boolean-greater-than(A, B)) | xsd:boolean |
A <= B | xsd:dateTime | xsd:dateTime | fn:not(op:dateTime-greater-than(A, B)) | xsd:boolean |
A >= B | 数値 | 数値 | logical-or(op:numeric-greater-than(A, B), op:numeric-equal(A, B)) | xsd:boolean |
A >= B | シンプルなリテラル | シンプルなリテラル | fn:not(op:numeric-equal(fn:compare(A, B), -1)) | xsd:boolean |
A >= B | xsd:string | xsd:string | fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), -1)) | xsd:boolean |
A >= B | xsd:boolean | xsd:boolean | fn:not(op:boolean-less-than(A, B)) | xsd:boolean |
A >= B | xsd:dateTime | xsd:dateTime | fn:not(op:dateTime-less-than(A, B)) | xsd:boolean |
XPath計算 | ||||
A * B | 数値 | 数値 | op:numeric-multiply(A, B) | 数値 |
A / B | 数値 | 数値 | op:numeric-divide(A, B) | 数値; but xsd:decimal if both operands are xsd:integer |
A + B | 数値 | 数値 | op:numeric-add(A, B) | 数値 |
A - B | 数値 | 数値 | op:numeric-subtract(A, B) | 数値 |
SPARQLテスト | ||||
A = B | RDF用語 | RDF用語 | RDFterm-equal(A, B) | xsd:boolean |
A != B | RDF用語 | RDF用語 | fn:not(RDFterm-equal(A, B)) | xsd:boolean |
「(EBV)」と共にマーク付けされたxsd:boolean関数の引数は、その引数の有効なブール値の評価によるxsd:booleanに強制されます:。
SPARQLの言語拡張は、演算子と演算子関数の間の付加的な関連付けを提供でき、これは、上記の表に列を加えることに等しいです。付加的な演算子は、上記で定義したセマンティクスにおける型エラー以外の結果に代わる結果をもたらさないかもしれません。この規則の結果は、FILTER
を未拡張の実装として適用した後に、SPARQLのFILTER
が少なくとも同じ中間バインディングを作成するかもしれないというものです。
「<」演算子の追加マッピングは、特に、ORDER BY
句で用いられるときに、オペランドの相対的な順序付けを制御すると予想されます。
この項では、SPARQLクエリ言語で導入された演算子と関数を定義します。例では、適切な文法構造によって呼び出される際の演算子の動作を示しています。
xsd:boolean BOUND (variable var)
var
が値にバインドされている場合は、真(true
)を返します。そうでない場合は、偽(false)を返します。NaNまたはINFの値を持つ変数は、バインドされているとみなされます。
データ:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . _:a foaf:givenName "Alice". _:b foaf:givenName "Bob" . _:b dc:date "2005-04-04T04:04:04Z"^^xsd:dateTime .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?givenName WHERE { ?x foaf:givenName ?givenName . OPTIONAL { ?x dc:date ?date } . FILTER ( bound(?date) ) }データ:
givenName |
---|
"Bob" |
変数を導入するOPTIONALグラフ・パターンを指定し、変数がバインドされていない(not bound)ことを確認するテストを行うことによってグラフ・パターンが表されていないことをテストできます。これは論理プログラミングでは、失敗による否定(Negation as Failure)と呼ばれます。
このクエリは、名前(name
)を持つが、日付(date
)の表現を持たない人にマッチします。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?name WHERE { ?x foaf:givenName ?name . OPTIONAL { ?x dc:date ?date } . FILTER (!bound(?date)) }
クエリ結果:
name |
---|
"Alice" |
Bobのdc:date
は既知であったため、"Bob"
はクエリのソリューションにはなりませんでした。
rdfTerm IF (expression1, expression2, expression3)
IF
関数形式は、最初の引数を評価して、それを有効なブール値として解釈し、EBVが真(true)であればexpression2
の値を返し、そうでなければexpression3
の値を返します。expression2
とexpression3
のうちの1つのみが評価されます。最初の引数の評価によってエラーが生じる場合、エラーはIF
式の評価が原因で生じます。
例: ?x = 2, ?z = 0であり、?yがクエリ・ソリューションにおいてバインドされていないとすると、次のようになります。
IF(?x = 2, "yes", "no") |
「yes」を返す。 |
IF(bound(?y), "yes", "no") |
「no」を返す。 |
IF(?x=2, "yes", 1/?z) |
「yes」を返し、式1/?z は評価されない。 |
IF(?x=1, "yes", 1/?z) |
エラーが生じる。 |
IF("2" > 1, "yes", "no") |
エラーが生じる。 |
rdfTerm COALESCE(expression, ....)
COALESCE
関数形式は、エラーなしに評価した最初の式のRDF用語の値を返します。SPARQLでは、バインドされていない変数を評価すると、エラーが生じます。
引数の評価結果がRDF用語にならない場合、エラーが生じます。エラーのない式の評価結果がない場合、エラーが生じます。
例: ?x = 2であり、?yがクエリ・ソリューションにおいてバインドされていないとすると、次のようになります。
COALESCE(?x, 1/0) |
2を返す。x の値 |
COALESCE(1/0, ?x) |
2を返す。 |
COALESCE(5, ?x) |
5を返す。 |
COALESCE(?y, 3) |
3を返す。 |
COALESCE(?y) |
y がバインドされていないため、エラーが生じる。 |
グラフ・パターンを取るフィルタ演算子EXISTS
があります。EXISTS
は、パターンが、現在のグループ・グラフ・パターン、データセットとクエリ評価のこの時点のアクティブ・グラフのバインディングを与えられたデータセットにマッチするかどうかに基づき、真(true
)/偽(false
)を返します。変数の追加バインディングは発生しません。NOT EXISTS
形式は、fn:not(EXISTS{...})
に置換します。
xsd:boolean NOT EXISTS { pattern }
pattern
がマッチすれば、偽(false
)を返します。そうでなければ、真(true)を返します
NOT EXISTS { pattern }
は、fn:not(EXISTS { pattern })
と同等ではありません。
xsd:boolean EXISTS
{ pattern }
pattern
がマッチすれば、真(true
)を返します。そうでなければ、偽(false)を返します。
現在のソリューション・マッピングでバインドされているpattern
の変数は、それがソリューション・マッピングで持っている値を取ります。現在のソリューション・マッピングでバインドされていないpattern
の変数は、パターン・マッチングに加わります。
これを容易にするために、SPARQL代数式を評価し、フィルタ・オペレーションでテストされているソリューション・マッピングを与えられたパターンにソリューションがあるかどうかに基づいて、真(true)または偽(false)を返す関数Existsを導入しました。
xsd:boolean xsd:boolean left || xsd:boolean right
左(left
)と右(right
)の論理和(OR
)を返します。logical-orがその引数の有効なブール値に基づいて演算を行うことに注意してください。
注意: ||
演算子のエラーの処理に関しては、17.2項フィルタ評価を参照してください。
xsd:boolean xsd:boolean left && xsd:boolean right
左(left
)と右(right
)の論理積(AND
)を返します。logical-andがその引数の有効なブール値に基づいて演算することに注意してください。
注意: &&
演算子のエラーの処理に関しては、17.2項フィルタ評価を参照してください。
xsd:boolean RDF term term1 = RDF用語 term2
RDF(Resource Description Framework): 概念および抽象構文[CONCEPTS]で定義されているとおり、term1
とterm2
が同じRDF用語*でない場合は、TRUEを返します。両方の引数がリテラルであるけれども同じRDF用語ではない場合は、型エラーを起こし、そうでない場合は、FALSEを返します。次のいずれかが真である場合は、term1
とterm2
は同じです。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice". _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Ms A.". _:b foaf:mbox <mailto:[email protected]> .
このクエリは、複数のfoaf:name
トリプルを持つ人を発見します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name1 ?name2 WHERE { ?x foaf:name ?name1 ; foaf:mbox ?mbox1 . ?y foaf:name ?name2 ; foaf:mbox ?mbox2 . FILTER (?mbox1 = ?mbox2 && ?name1 != ?name2) }
クエリ結果:
name1 | name2 |
---|---|
"Alice" | "Ms A." |
"Ms A." | "Alice" |
特定の日時(2005年の元日(+00:00の時間帯尺度))にアノテーションが付与されたドキュメントに関するこのクエリは、RDF用語は同じではありませんが、同等な値を持っています。
@prefix a: <http://www.w3.org/2000/10/annotation-ns#> . @prefix dc: <http://purl.org/dc/elements/1.1/> . _:b a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:b dc:date "2004-12-31T19:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?annotates WHERE { ?annot a:annotates ?annotates . ?annot dc:date ?date . FILTER ( ?date = xsd:dateTime("2005-01-01T00:00:00Z") ) }
annotates |
---|
<http://www.w3.org/TR/rdf-sparql-query/> |
* 2つの型付きリテラルにRDFterm-equalを呼び出すことで、同等な値をテストします。拡張された実装には、付加的なデータ型のサポートがあるかもしれません。未サポートのデータ型(および、異なる字句形式とデータ型IRI)の同等性をテストするクエリを処理する実装はエラーを返し、値が同等かどうかを決定できなかったことを示します。例えば、"iiii"^^my:romanNumeral = "iv"^^my:romanNumeral
か"iiii"^^my:romanNumeral != "iv"^^my:romanNumeral
のいずれかのテストを行った場合、未拡張の実装にエラーが生じます。
xsd:boolean sameTerm (RDF用語 term1, RDF term term2)
RDF(Resource Description Framework): 概念および抽象構文[CONCEPTS]で定義されているとおり、term1
とterm2
が同じRDF用語である場合は、TRUEを返し、そうでない場合は、FALSEを返します。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice". _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Ms A.". _:b foaf:mbox <mailto:[email protected]> .
このクエリは、複数のfoaf:name
トリプルを持つ人を発見します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name1 ?name2 WHERE { ?x foaf:name ?name1 ; foaf:mbox ?mbox1 . ?y foaf:name ?name2 ; foaf:mbox ?mbox2 . FILTER (sameTerm(?mbox1, ?mbox2) && !sameTerm(?name1, ?name2)) }
クエリ結果:
name1 | name2 |
---|---|
"Alice" | "Ms A." |
"Ms A." | "Alice" |
RDFterm-equalとは異なり、sameTermは、未サポートのデータ型を持つ非同等な型付きリテラルをテストするために使用できます。
@prefix : <http://example.org/WMterms#> . @prefix t: <http://example.org/types#> . _:c1 :label "Container 1" . _:c1 :weight "100"^^t:kilos . _:c1 :displacement "100"^^t:liters . _:c2 :label "Container 2" . _:c2 :weight "100"^^t:kilos . _:c2 :displacement "85"^^t:liters . _:c3 :label "Container 3" . _:c3 :weight "85"^^t:kilos . _:c3 :displacement "85"^^t:liters .
PREFIX : <http://example.org/WMterms#> PREFIX t: <http://example.org/types#> SELECT ?aLabel1 ?bLabel WHERE { ?a :label ?aLabel . ?a :weight ?aWeight . ?a :displacement ?aDisp . ?b :label ?bLabel . ?b :weight ?bWeight . ?b :displacement ?bDisp . FILTER ( sameTerm(?aWeight, ?bWeight) && !sameTerm(?aDisp, ?bDisp)) }
aLabel | bLabel |
---|---|
"Container 1" | "Container 2" |
"Container 2" | "Container 1" |
"100"^^t:kilos = "85"^^t:kilos
のテストが、その生成されうるソリューションを排除して、エラーをもたらすため、同じ重さの箱のテストは「=」演算子(RDFterm-equal)でも行えます。
boolean rdfTerm
IN (expression, ...)
IN
演算子は、左側のRDF用語が右側の式のリストの値で見つかるか否かをテストします。このテストは、演算子マッピングで定められているとおり、「=」演算子で行い、それによって同じ値に対するテストが行われます。
右側の0の用語のリストは、正当です。
テストを行っているRDF用語が用語のリストの他の場所で見つからなければ、比較におけるエラーにより、IN
式にエラーが生じます。
このIN
演算子は、次のSPARQL式と同等です。
(lhs = expression1) || (lhs = expression2) || ...
例:
2 IN (1, 2, 3) |
真 |
2 IN () |
偽 |
2 IN (<http://example/iri>, "str", 2.0) |
真 |
2 IN (1/0, 2) |
真 |
2 IN (2, 1/0) |
真 |
2 IN (3, 1/0) |
エラーが生じる。 |
boolean rdfTerm
NOT IN (expression, ...)
NOT IN
演算子は、左側のRDF用語が右側の式のリストの値で見つからないか否かのテストを行います。このテストは、演算子マッピングで定められているとおり、「!=」演算子で行い、それによって同じではない値に対するテストが行われます。
右側の0の用語のリストは正当です。
テストを行っているRDF用語が用語のリストの他の場所のリストで見つからなければ、比較におけるエラーにより、NOT IN式にエラーが生じます。
NOT IN
演算子は、次のSPARQL式と同等です。
(lhs != expression1) && (lhs != expression2) && ...
NOT IN (...)
は、!(IN (...))
と同等です。
例:
2 NOT IN (1, 2, 3) |
偽 |
2 NOT IN () |
真 |
2 NOT IN (<http://example/iri>, "str", 2.0) |
偽 |
2 NOT IN (1/0, 2) |
偽 |
2 NOT IN (2, 1/0) |
偽 |
2 NOT IN (3, 1/0) |
エラーが生じる。 |
xsd:boolean isIRI (RDF term term) xsd:boolean isURI (RDF term term)
用語(term
)がIRIである場合は、真(true
)を返します。そうでない場合は、偽(false
)を返します。isURIは、isIRI演算子の別のスペルです。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice". _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Bob" . _:b foaf:mbox "[email protected]" .
このクエリは、名前(name
)と、IRIであるmbox
を持つ人にマッチします。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name ; foaf:mbox ?mbox . FILTER isIRI(?mbox) }
クエリ結果:
name | mbox |
---|---|
"Alice" | <mailto:[email protected]> |
xsd:boolean isBlank (RDF term term)
用語(term
)が空白ノードである場合は、真(true
)を返します。そうでない場合は、偽(false
)を返します。
@prefix a: <http://www.w3.org/2000/10/annotation-ns#> . @prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:a dc:creator "Alice B. Toeclips" . _:b a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:b dc:creator _:c . _:c foaf:given "Bob". _:c foaf:family "Smith".
このクエリは、名前を表すためにFOAF語彙の述語を用いているdc:creator
を持つ人にマッチします。
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?given ?family WHERE { ?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . ?annot dc:creator ?c . OPTIONAL { ?c foaf:given ?given ; foaf:family ?family } . FILTER isBlank(?c) }
クエリ結果:
given | family |
---|---|
"Bob" | "Smith" |
この例では、dc:creator
という述語の目的語が2つありましたが、たった1つの(_:c
)が空白ノードでした。
xsd:boolean isLiteral (RDF term term)
用語(term
)がリテラルである場合、真(true
)を返します。そうでない場合は、偽(false
)を返します。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice". _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Bob" . _:b foaf:mbox "[email protected]" .
このクエリは、名前(name
)と、リテラルであるmbox
を持つ人にマッチする点を除いて、17.4.2.1のものと類似しています。これは、エラーのあるデータを探すために使用できるでしょう(foaf:mbox
は、目的語として1つのIRIのみを持っているはずです)。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name ; foaf:mbox ?mbox . FILTER isLiteral(?mbox) }
クエリ結果:
name | mbox |
---|---|
"Bob" | "[email protected]" |
xsd:boolean isNumeric (RDF term term)
用語(term
)が数値であれば、真(true
)を返します。そうでなければ偽(false
)を返します。用語(term
)は、それが適切なデータ・タイプ(オペランド・データ型の項を参照)を持ち、有効な字句形式を持っていれば数値で、数値の引数を取る関数と演算子の有効な引数になります。
例:
isNumeric(12) |
真 |
isNumeric("12") |
偽 |
isNumeric("12"^^xsd:nonNegativeInteger) |
真 |
isNumeric("1200"^^xsd:byte) |
偽 |
isNumeric(<http://example/>) |
偽 |
simple literal STR (literal ltrl) simple literal STR (IRI rsrc)
ltrl
(リテラル)の字句形式を返し、rsrc
(IRI)コードポイント表現を返します。これは、IRIの部分、例えば、ホスト名を調べるのに役に立ちます。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice". _:a foaf:mbox <mailto:[email protected]> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:[email protected]> .
このクエリは、次のとおり、自分達のfoafプロフィールでwork.example
のアドレスを使用する人々の集合を選び出します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name ; foaf:mbox ?mbox . FILTER regex(str(?mbox), "@work\\.example$") }
クエリ結果:
name | mbox |
---|---|
"Alice" | <mailto:[email protected]> |
simple literal LANG (literal ltrl)
ltrl
の言語タグ(それがある場合)を返します。ltrl
に言語タグがない場合は、""
を返します。RDFデータ・モデルが空の言語タグを持つリテラルを含んでいないことに注意してください。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Robert"@en. _:a foaf:name "Roberto"@es. _:a foaf:mbox <mailto:[email protected]> .
このクエリは、スペイン語のfoaf:name
とfoaf:mbox
を発見します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name ; foaf:mbox ?mbox . FILTER ( lang(?name) = "es" ) }
クエリ結果:
name | mbox |
---|---|
"Roberto"@es | <mailto:[email protected]> |
iri DATATYPE (literal literal)
リテラル(literal
)のデータ型IRIを返します。
xsd:string
を返します。rdf:langString
を返します。@prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix eg: <http://biometrics.example/ns#> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . _:a foaf:name "Alice". _:a eg:shoeSize "9.5"^^xsd:float . _:b foaf:name "Bob". _:b eg:shoeSize "42"^^xsd:integer .
このクエリは、整数であるshoeSizeを持つすべての人のfoaf:name
とfoaf:shoeSize
を発見します。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX eg: <http://biometrics.example/ns#> SELECT ?name ?shoeSize WHERE { ?x foaf:name ?name ; eg:shoeSize ?shoeSize . FILTER ( datatype(?shoeSize) = xsd:integer ) }
クエリ結果:
name | shoeSize |
---|---|
"Bob" | 42 |
SPARQL 1.0では、DATATYPE
関数は、言語タグ付きリテラルに対しては定義されていませんでした。したがって、DATATYPE
が言語タグ付きリテラルで呼び出されると、未拡張の実装ではエラーが生じるでしょう。演算子の拡張性では、エラーを発生させるのではなく、実装が結果を返すことが認められています。SPARQL 1.1は、言語タグ付きリテラルに適用されたDATATYPE
の結果をrdf:langString
と定義しています。
rdf:langString
を使用しています。これは、rdf:langString
が最新のRDF勧告の一部になるまで/ならない限り、実験中(かつ、非規範的)であると考えるべきです。iri IRI(simple literal
) iri IRI(xsd:string) iri IRI(iri) iri URI(simple literal
) iri URI(xsd:string) iri URI(iri)
IRI
関数は、文字列の引数の解決により、IRIを生成します(RFC 3986およびRFC 3987、または、RFC 3986やRFC 3987に取って代わった最新のRFCを参照)。IRIはクエリの基底IRIに対して解決され、絶対IRIにならなければなりません。
URI
関数はIRI
の同意語です。
関数がIRIを渡せば、IRIがそのまま返されます。
シンプルなリテラル以外のいかなるRDF用語を渡しても、xsd:stringまたはIRIはエラーです。
実装はIRIを正規化できます(MAY)。
例:
IRI("http://example/") |
<http://example/> |
IRI(<http://example/>) |
<http://example/> |
blank node BNODE()
blank node BNODE(simple literal)
blank node BNODE(xsd:string)
BNODE
関数は、クエリが行われているデータセット内のあらゆる空白ノードとも、このコンストラクタの呼び出しによって他のクエリ・ソリューションのために作成されるあらゆる空白ノードとも異なる空白ノードを生成します。引数形式が用いられていない場合は、呼び出しごとに、別々の空白ノードが作成されます。シンプルなリテラルの形式を用いた場合は、異なるシンプルなリテラルに対しては、呼び出しごとに別々の空白ノードが生成され、1つのソリューション・マッピングの式の中で同じシンプルなリテラルを持つ呼び出しに対しては範囲内の同じ空白ノードが生成されます。
この機能は、SPARQL CONSTRUCTテンプレートの空白ノードの処理と互換性があります。
literal STRDT(simple literal lexicalForm, IRI datatypeIRI)
STRDT
関数は、字句形式および引数で指定された型を持つリテラルを生成します。
STRDT("123", xsd:integer) |
"123"^^<http://www.w3.org/2001/XMLSchema#integer> |
STRDT("iiii", <http://example/romanNumeral>) |
"iiii"^^<http://example/romanNumeral> |
literal STRLANG(simple literal lexicalForm, simple literal langTag)
STRLANG
関数は、字句形式および引数で指定された言語タグを持つリテラルを生成します。
STRLANG("chat", "en") |
"chat"@en |
iri UUID()
UUID URNUUID URNスキームから新たなIRIを返します。UUID()
の呼び出しごとに異なるUUIDを返します。「nil」UUID(すべて0)ではあってはなりません。UUIDの変数とバージョンは、実装に依存します。
UUID() |
<urn:uuid:b9302fb5-642e-4d3b-af19-29a8f6d894c9> |
関数(例えば、REGEX、STRLEN、CONTAINS)には、文字列リテラルを引数として取り、シンプルなリテラル、言語タグ付きプレーン・リテラル、または、データ型xsd:stringを持つリテラルを受け入れるものがあります。それは、後でリテラルの字句形式に影響を与えます。
このために、関数の記述でstring literal
(文字列リテラル)という用語を用います。他のRDF用語を用いると、エラーが生じる関数が呼び出されるでしょう。
STRSTARTS、STRENDS、CONTAINS、STRBEFOREとSTRAFTERの関数は、2つの引数を取ります。これらの引数には互換性がなくてはならず、そうでない場合には、これらの関数の1つを呼び出すとエラーが生じます。
2つの引数の互換性は、次のとおりに定義されています。
引数1 | 引数2 | 互換? |
---|---|---|
"abc" | "b" | はい |
"abc" | "b"^^xsd:string | はい |
"abc"^^xsd:string | "b" | はい |
"abc"^^xsd:string | "b"^^xsd:string | はい |
"abc"@en | "b" | はい |
"abc"@en | "b"^^xsd:string | はい |
"abc"@en | "b"@en | はい |
"abc"@fr | "b"@ja | いいえ |
"abc" | "b"@ja | いいえ |
"abc" | "b"@en | いいえ |
"abc"^^xsd:string | "b"@en | いいえ |
xsd:integer STRLEN(string literal str)
strlen
関数は、XPathのfn:string-length関数に相当し、リテラルの字句形式の文字の長さと等しいxsd:integer
を返します。
strlen("chat") |
4 |
strlen("chat"@en) |
4 |
strlen("chat"^^xsd:string) |
4 |
string literal SUBSTR(string literal source, xsd:integer startingLoc)
string literal SUBSTR(string literal source, xsd:integer startingLoc, xsd:integer length)
substr
関数は、XPathのfn:substring関数に相当し、source
(情報源)の入力パラメータとして、同じ種類のリテラル(シンプルなリテラル、言語タグを持つリテラル、xsd:string
という型を持つリテラル)を返しますが、それは、情報源の字句形式の部分文字列(substring)から生成された字句形式を持っています。
引数startingLoc
とlength
は、xsd:integerの派生型でありえます。
文字列の最初の文字の指数は1です。
substr("foobar", 4) |
"bar" |
substr("foobar"@en, 4) |
"bar"@en |
substr("foobar"^^xsd:string, 4) |
"bar"^^xsd:string |
substr("foobar", 4, 1) |
"b" |
substr("foobar"@en, 4, 1) |
"b"@en |
substr("foobar"^^xsd:string, 4, 1) |
"b"^^xsd:string |
string literal UCASE(string literal str)
UCASE
関数は、XPathのfn:upper-case関数に相当します。これは、字句形式が、大文字の引数の字句形式である文字列リテラルを返します。
ucase("foo") |
"FOO" |
ucase("foo"@en) |
"FOO"@en |
ucase("foo"^^xsd:string) |
"FOO"^^xsd:string |
string literal LCASE(string literal str)
LCASE
関数は、XPathのfn:lower-case関数に相当します。これは、字句形式が、小文字の引数の字句形式である文字列リテラルを返します。
lcase("BAR") |
"bar" |
lcase("BAR"@en) |
"bar"@en |
lcase("BAR"^^xsd:string) |
"bar"^^xsd:string |
xsd:boolean STRSTARTS(string literal arg1, string literal arg2)
STRSTARTS
関数は、XPathのfn:starts-with関数に相当します。引数は、互換性のある引数でなければならず、そうでない場合には、エラーが生じます。
このような対が入力されると、関数は、arg1
の字句形式がarg2
の字句形式で始まる場合に真(true)を返し、そうでない場合に偽(false)を返します。
strStarts("foobar", "foo") |
true |
strStarts("foobar"@en, "foo"@en) |
true |
strStarts("foobar"^^xsd:string, "foo"^^xsd:string) |
true |
strStarts("foobar"^^xsd:string, "foo") |
true |
strStarts("foobar", "foo"^^xsd:string) |
true |
strStarts("foobar"@en, "foo") |
true |
strStarts("foobar"@en, "foo"^^xsd:string) |
true |
xsd:boolean STRENDS(string literal arg1, string literal arg2)
STRENDS
関数は、XPathのfn:ends-with関数に相当します。引数は、互換性のある引数でなければならず、そうでない場合には、エラーが生じます。
このような対が入力されると、関数は、arg1
の字句形式がarg2
の字句形式で終了する場合に真(true)を返し、そうでない場合に偽(false)を返します。
strEnds("foobar", "bar") |
true |
strEnds("foobar"@en, "bar"@en) |
true |
strEnds("foobar"^^xsd:string, "bar"^^xsd:string) |
true |
strEnds("foobar"^^xsd:string, "bar") |
true |
strEnds("foobar", "bar"^^xsd:string) |
true |
strEnds("foobar"@en, "bar") |
true |
strEnds("foobar"@en, "bar"^^xsd:string) |
true |
xsd:boolean CONTAINS(string literal arg1, string literal arg2)
CONTAINS
関数は、XPathのfn:containsに相当します。引数は、互換性のある引数でなければならず、そうでない場合には、エラーが生じます。
contains("foobar", "bar") |
true |
contains("foobar"@en, "foo"@en) |
true |
contains("foobar"^^xsd:string, "bar"^^xsd:string) |
true |
contains("foobar"^^xsd:string, "foo") |
true |
contains("foobar", "bar"^^xsd:string) |
true |
contains("foobar"@en, "foo") |
true |
contains("foobar"@en, "bar"^^xsd:string) |
true |
literal STRBEFORE(string literal arg1, string literal arg2)
STRBEFORE
関数は、XPathのfn:substring-before関数に相当します。引数は、互換性のある引数でなければならず、そうでない場合には、エラーが生じます。
互換性を持つ引数では、2番目の引数の字句部分が最初の引数の字句部分の部分文字列(substring)として存在する場合、関数は最初の引数arg1
と同じ種類のリテラル(シンプルなリテラル、同じ言語タグを持つプレーン・リテラル、xsd:string)を返します。結果の字句形式は、最初のarg2
の字句形式の前にarg1
の字句形式の部分文字列(substring)が置かれたものとなります。arg2
の字句形式が空の文字列であれば、マッチしたとみなされ、結果の字句形式は空の文字列です。
そのような文字列の発生がなければ、空のシンプルなリテラルが返されます。
strbefore("abc","b") | "a" |
strbefore("abc"@en,"bc") | "a"@en |
strbefore("abc"@en,"b"@cy) | error |
strbefore("abc"^^xsd:string,"") | ""^^xsd:string |
strbefore("abc","xyz") | "" |
strbefore("abc"@en, "z"@en) | "" |
strbefore("abc"@en, "z") | "" |
strbefore("abc"@en, ""@en) | ""@en |
strbefore("abc"@en, "") | ""@en |
literal STRAFTER(string literal arg1, string literal arg2)
STRAFTER
機能は、XPathのfn:substring-after関数に相当します。引数は、互換性のある引数でなければならず、そうでない場合には、エラーが生じます。
互換性を持つ引数では、2番目の引数の字句部分が最初の引数の字句部分の部分文字列(substring)として存在した場合、関数は最初の引数arg1と同じ種類のリテラル(シンプルなリテラル、同じ言語タグを持つプレーン・リテラル、xsd:string)を返します。結果の字句形式は、最初に発生したarg2
の字句形式の後にarg1の字句形式の部分文字列(substring)が置かれたものとなります。arg2
の字句形式が空の文字列であれば、マッチしたとみなされ、結果の字句形式はarg1
の字句形式です。
そのような文字列の発生がなければ、空のシンプルなリテラルが返されます。
strafter("abc","b") | "c" |
strafter("abc"@en,"ab") | "c"@en |
strafter("abc"@en,"b"@cy) | error |
strafter("abc"^^xsd:string,"") | "abc"^^xsd:string |
strafter("abc","xyz") | "" |
strafter("abc"@en, "z"@en) | "" |
strafter("abc"@en, "z") | "" |
strafter("abc"@en, ""@en) | "abc"@en |
strafter("abc"@en, "") | "abc"@en |
simple literal ENCODE_FOR_URI(string literal ltrl)
ENCODE_FOR_URI
関数は、XPathのfn:encode-for-uri関数に相当します。これは、fn:encode-for-uri関数で予約文字を置換した後に、その入力の字句形式から得られた字句形式を持つシンプルなリテラルを返します。
encode_for_uri("Los Angeles") |
"Los%20Angeles" |
encode_for_uri("Los Angeles"@en) |
"Los%20Angeles" |
encode_for_uri("Los Angeles"^^xsd:string) |
"Los%20Angeles" |
string literal CONCAT(string literal ltrl1 ... string literal ltrln)
CONCAT
関数は、XPathの fn:concat関数に相当します。この関数では、引数として文字列リテラルが認められています。
返されたリテラルの字句形式は、その入力の字句形式を連結することで得られます。入力されたリテラルがすべてxsd:string
という型の型付きリテラルであれば、返されたリテラルもxsd:string
という型で、入力されたリテラルがすべて同一の言語タグを持つプレーン・リテラルであれば、返されたリテラルは、同じ言語タグを持つプレーン・リテラルで、その他の場合はすべて、返されたリテラルはシンプルなリテラルです。
concat("foo", "bar") |
"foobar" |
concat("foo"@en, "bar"@en) |
"foobar"@en |
concat("foo"^^xsd:string, "bar"^^xsd:string) |
"foobar"^^xsd:string |
concat("foo", "bar"^^xsd:string) |
"foobar" |
concat("foo"@en, "bar") |
"foobar" |
concat("foo"@en, "bar"^^xsd:string) |
"foobar" |
xsd:boolean langMatches (simple literal language-tag, simple literal language-range)
language-tag
(最初の引数)が、[RFC4647]の3.3.1項で定義されている基本的なフィルタリング・スキームでlanguage-range
(2番目の引数)にマッチする場合は、真(true
)を返します。language-range
は、[RFC4647]の2.1.項の言語タグのマッチングにあるとおりの基本言語の範囲です。「*」のlanguage-range
は、任意の空でないlanguage-tag
文字列にマッチします。
@prefix dc: <http://purl.org/dc/elements/1.1/> . _:a dc:title "That Seventies Show"@en . _:a dc:title "Cette Serie des Annees Soixante-dix"@fr . _:a dc:title "Cette Serie des Annees Septante"@fr-BE . _:b dc:title "Il Buono, il Bruto, il Cattivo" .
このクエリでは、英語で「That Seventies Show」として知られているショーに対するフランス語のタイトルを発見するために、langMatches
とlang
を使用しています。
PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?title WHERE { ?x dc:title "That Seventies Show"@en ; dc:title ?title . FILTER langMatches( lang(?title), "FR" ) }
クエリ結果:
title |
---|
"Cette Serie des Annees Soixante-dix"@fr |
"Cette Serie des Annees Septante"@fr-BE |
成句的表現langMatches( lang( ?v ), "*" )
は、lang( ?v )
が空の文字列を返すため、言語タグなしではリテラルにマッチしないでしょう。そのため、
PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?title WHERE { ?x dc:title ?title . FILTER langMatches( lang(?title), "*" ) }
は、言語タグを持つタイトルのすべてを報告するでしょう。
title |
---|
"That Seventies Show"@en |
"Cette Serie des Annees Soixante-dix"@fr |
"Cette Serie des Annees Septante"@fr-BE |
xsd:boolean REGEX (string literal text, simple literal pattern) xsd:boolean REGEX (string literal text, simple literal pattern, simple literal flags)
正規表現パターン(pattern
)に対してテキスト(text
)をマッチさせるためにfn:matches関数を呼び出します。正規表現言語は、XQuery 1.0とXPath 2.0関数および演算子の7.6.1 正規表現構文[FUNCOP]の項で定義されています。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alice". _:b foaf:name "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name WHERE { ?x foaf:name ?name FILTER regex(?name, "^ali", "i") }
クエリ結果:
name |
---|
"Alice" |
string literal REPLACE (string literal arg, simple literal pattern, simple literal replacement ) string literal REPLACE (string literal arg, simple literal pattern, simple literal replacement, simple literal flags)
REPLACE
関数は、XPathのfn:replace関数に相当します。これは、個々の重複のない正規表現patternを、置換文字列に置き換えます。正規表現マッチングには、修飾語フラグが含まれているかもしれません。REGEXを参照してください。
replace("abcd", "b", "Z") | "aZcd" |
replace("abab", "B", "Z","i") | "aZaZ" |
replace("abab", "B.", "Z","i") | "aZb" |
numeric ABS (numeric term)
arg
の絶対値を返します。arg
が数値でなければ、エラーが生じます。
この関数は、XDMのデータ型を持つ用語のfn:numeric-absと同じです。
abs(1) |
1 |
abs(-1.5) |
1.5 |
numeric ROUND (numeric term)
引数に最も近い端数のない数を返します。そのような数が2つある場合には、正の無限大に最も近い数が返されます。arg
が数値でなければ、エラーが生じます。
この関数は、XDMのデータ型を持つ用語のfn:numeric-roundと同じです。
round(2.4999) |
2.0 |
round(2.5) |
3.0 |
round(-2.5) |
-2.0 |
numeric CEIL (numeric term)
arg
の値以上の端数のない最小の(負の無限大に最も近い)数を返します。arg
が数値でなければ、エラーが生じます。
この関数は、XDMのデータ型を持つ用語のfn:numeric-ceilと同じです。
ceil(10.5) |
11.0 |
ceil(-10.5) |
-10.0 |
numeric FLOOR (numeric term)
arg
の値以下の端数のない最大の(正の無限大に最も近い)数を返します。arg
が数値でない場合、エラーが生じます。
この関数は、XDMのデータ型を持つ用語のfn:numeric-floorと同じです。
floor(10.5) |
10.0 |
floor(-10.5) |
-11.0 |
xsd:dateTime NOW ()
現在実行しているクエリに対するXSD dateTimeの値を返します。1つのクエリの実行の中では、この関数の呼び出しで返される値はすべて同じでなければなりません。返された正確な瞬間の日時は明示されません。
now() |
"2011-01-10T14:45:13.815-05:00"^^xsd:dateTime |
xsd:integer YEAR (xsd:dateTime arg)
arg
の年の部分を整数で返します。
この関数は、fn:year-from-dateTimeに相当します。
year("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
2011 |
xsd:integer MONTH (xsd:dateTime arg)
arg
の月の部分を整数で返します。
この関数は、fn:month-from-dateTimeに相当します。
month("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
1 |
xsd:integer DAY (xsd:dateTime arg)
arg
の日の部分を整数で返します。
この関数は、fn:day-from-dateTimeに相当します。
day("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
10 |
xsd:integer HOURS (xsd:dateTime arg)
arg
の時間の部分を整数で返します。値は、XSD dateTimeの字句形式で示されている通りです。
この関数は、fn:hours-from-dateTimeに相当します。
hours("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
14 |
xsd:integer MINUTES (xsd:dateTime arg)
arg
の字句形式の分の部分を返します。値は、XSD dateTimeの字句形式で示されている通りです。
この関数は、fn:minutes-from-dateTimeに相当します。
minutes("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
45 |
xsd:decimal SECONDS (xsd:dateTime arg)
arg
の字句形式の秒の部分を返します。
この関数は、fn:seconds-from-dateTimeに相当します。
seconds("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
13.815 |
xsd:dayTimeDuration TIMEZONE (xsd:dateTime arg)
arg
の時間帯の部分をxsd:dayTimeDurationとして返します。時間帯がない場合、エラーが生じます。
この関数は、時間帯のないリテラルの処理を除き、fn:timezone-from-dateTimeに相当します。
timezone("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
"-PT5H"^^xsd:dayTimeDuration |
timezone("2011-01-10T14:45:13.815Z"^^xsd:dateTime) |
"PT0S"^^xsd:dayTimeDuration |
timezone("2011-01-10T14:45:13.815"^^xsd:dateTime) |
error |
simple literal MD5 (simple literal arg)
simple literal MD5 (xsd:string arg)
xsd:string
をシンプルなリテラルか字句形式のUTF-8で処理したMD5チェックサムを16進数の文字列で返します。16進数は、小文字であるべきです(SHOULD)。
MD5("abc") |
"900150983cd24fb0d6963f7d28e17f72" |
MD5("abc"^^xsd:string) |
"900150983cd24fb0d6963f7d28e17f72" |
simple literal SHA1 (simple literal arg)
simple literal SHA1 (xsd:string arg)
xsd:string
をシンプルなリテラルか字句形式のUTF-8で処理したSHA1チェックサムを16進数の文字列で返します。16進数は、小文字であるべきです(SHOULD)。
SHA1("abc") |
"a9993e364706816aba3e25717850c26c9cd0d89d" |
SHA1("abc"^^xsd:string) |
"a9993e364706816aba3e25717850c26c9cd0d89d" |
simple literal SHA256 (simple literal arg)
simple literal SHA256 (xsd:string arg)
xsd:string
をシンプルなリテラルか字句形式のUTF-8で処理したSHA256チェックサムを16進数の文字列で返します。16進数は、小文字であるべきです(SHOULD)。
SHA256("abc") |
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" |
SHA256("abc"^^xsd:string) |
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" |
simple literal SHA384 (simple literal arg)
simple literal SHA384 (xsd:string arg)
xsd:string
をシンプルなリテラルか字句形式のUTF-8で処理したSHA384チェックサムを16進数の文字列で返します。16進数は、小文字であるべきです(SHOULD)。
SHA384("abc") |
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" |
SHA384("abc"^^xsd:string) |
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" |
simple literal SHA512 (simple literal arg)
simple literal SHA512 (xsd:string arg)
xsd:string
をシンプルなリテラルか字句形式のUTF-8で処理したSHA512チェックサムを16進数の文字列で返します。16進数は、小文字であるべきです(SHOULD)。
SHA512("abc") |
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" |
SHA512("abc"^^xsd:string) |
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" |
SPARQLは、XQuery 1.0とXPath 2.0関数および演算子[FUNCOP]の17.1 プリミティブ型からプリミティブ型へのキャスティングで定義されているXPathコンストラクタ関数のサブセットをインポートします。SPARQLコンストラクタは、RDFデータ・モデルが規定しているSPARQLオペランド・データ型と付加的なデータ型のXPathコンストラクタのすべてを含んでいます。SPARQLのキャスティングは、情報源の型のオペランドにターゲット型に対するコンストラクタ関数を呼び出すことによって実行されます。
XPathは、1つのXMLスキーマ・データ型から別のデータ型へのキャストのみを定義しています。残りのキャストは、次の通り定義されています。
xsd:string
にキャストすると、そのIRIを構成するコードポイントの字句値を持つ型付きリテラル、およびxsd:string
のデータ型が作成されます。xsd:string
をキャストしたときの生成物であると定義されます。次の表では、キャスティング操作が常に許されるもの(Y)、決して許されないもの(N)、字句値次第のもの(M)にまとめています。例えば、xsd:string
(最初の行)からxsd:float
(2番目の列)へのキャスティング操作は、字句値(M)次第です。
bool = xsd:boolean
dbl = xsd:double
flt = xsd:float
dec = xsd:decimal
int = xsd:integer
dT = xsd:dateTime
str = xsd:string
IRI = IRI
ltrl =simple literal
From \ To | str | flt | dbl | dec | int | dT | bool |
---|---|---|---|---|---|---|---|
str | Y | M | M | M | M | M | M |
flt | Y | Y | Y | M | M | N | Y |
dbl | Y | Y | Y | M | M | N | Y |
dec | Y | Y | Y | Y | Y | N | Y |
int | Y | Y | Y | Y | Y | N | Y |
dT | Y | N | N | N | N | Y | N |
bool | Y | Y | Y | Y | Y | N | Y |
IRI | Y | N | N | N | N | N | N |
ltrl | Y | M | M | M | M | M | M |
ある条件でエラーを返すように定められている関数や演算子も、有効な拡張ポイントであることに注意すべきです。つまり、実装では、これらのエラーが発生した場合には非エラー値が返され、この勧告との適合性も保たれます。
PrimaryExpressionの文法規則は、IRIで指定された拡張関数への呼び出しでありえます。拡張関数は、RDF用語のいくつかを引数と見なして、RDF用語を返します。これらの関数のセマンティクスは、関数を識別するIRIによって識別されます。
拡張関数を用いるSPARQLクエリは、相互運用性を制限する可能性があります。
例として、func:even
と呼ばれる関数を取り上げます。
xsd:boolean
func:even
(numeric
value
)
この関数は、次のとおり、そういうものとしてFILTERに呼び出されるでしょう。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX func: <http://example.org/functions#> SELECT ?name ?id WHERE { ?x foaf:name ?name ; func:empId ?id . FILTER (func:even(?id)) }
2番目の例では、2つの地点の間の距離を計算する関数aGeo:distance
について考えてみます。ここでは、これをグルノーブル(Grenoble)付近の場所を発見するために用います。
xsd:double
???aGeo:distance
(numeric
x1
,numeric
y1
,numeric
x2
,numeric
y2
)
PREFIX aGeo: <http://example.org/geo#> SELECT ?neighbor WHERE { ?a aGeo:placeName "Grenoble" . ?a aGeo:locationX ?axLoc . ?a aGeo:locationY ?ayLoc . ?b aGeo:placeName ?neighbor . ?b aGeo:locationX ?bxLoc . ?b aGeo:locationY ?byLoc . FILTER ( aGeo:distance(?axLoc, ?ayLoc, ?bxLoc, ?byLoc) < 10 ) . }
拡張関数は、コアSPARQL仕様でサポートされていないアプリケーション・データ型をテストするために用いられるかもしれず、例えばこれは、別の日付フォーマットからXSD dateTime RDF用語へのデータ型フォーマット間の変換であるかもしれません。
この項では、クエリ文字列とRDFデータセットを前提に、グラフ・パターンとソリューション修飾子の評価のに対する正しい行動を定義します。これは、SPARQL実装がここで定義されたプロセスを使用しなければならないということを意味しません。
SPARQLクエリを実行した結果は、SPARQLクエリを文字列として開始し、その文字列を抽象構文形式に変え、次に、その抽象構文をSPARQLの代数の演算子で構成されるSPARQL抽象クエリに変える、という一連のステップで定義されます。その後、この抽象クエリは、RDFデータセットで評価されます。
SPARQLは、IRI[RFC3987]の用語で定義されています。IRIは、スペースの使用を省略するRDF URI参照のサブセットです。
IをすべてのIRIの集合とする。
RDF-LをすべてのRDFリテラルの集合とする。
RDF-BをすべてのRDFグラフにおける空白ノードの集合とする。
RDF用語の集合、RDF-Tは、I ∪ RDF-L ∪ RDF-Bです。
RDF用語のこの定義は、 RDFデータ・モデルのいくつかの基本的な概念をまとめていますが、RDF URI参照ではなくIRIを参照言するように更新されています。
定義: Simple Literal
The set of Simple Literals is the set of all RDF Literals with no language tag or datatype IRI.
RDFデータセットは以下の集合です。
{ G, (<u1>, G1), (<u2>, G2), . . .
(<un>, Gn) }
ここでは、Gと各Giはグラフであり、各<ui>はIRIです。各<ui>はdistinctです。
Gはデフォルト・グラフと呼ばれます。(<ui>, Gi)は名前付きグラフと呼ばれます。
アクティブ・グラフは、基本グラフパターン・マッチングに用いられるデータセットのグ ラフです。
Let DS1 =
{ G1, (<u11>, G11), (<u12>, G12), . . .
(<u1n>, G1n) },
and DS2 =
{ G2, (<u21>, G21), (<u22>, G22), . . .
(<u2m>, G2m) }
then we define the RDF Dataset Merge of DS1 and DS2 to be:
DS={ G, (<u1>, G1), (<u2>, G2), . . .
(<uk>, Gk) }
where:
Write N1 for { <u1j> j = 1 to n }
Write N2 for { <u2j> j = 1 to m }
クエリ変数は、Vが無限であり、RDF-Tと互いに素な集合Vのメンバーです。
トリプル・パターンは、次の集合のメンバーです。
(RDF-T ∪ V) x (I ∪ V) x (RDF-T ∪ V)
トリプル・パターンのこの定義には、リテラルの主語が含まれています。これは、RDF-コアで注記されています。
「[RDFコア・ワーキンググループは]リテラルが主語であってはならない理由がないことを 承知していると述べました。そして、より制限のない憲章を持つ将来のWGは、ステートメン トの主語としてのリテラルを許容するように構文を拡張するかもしれません。」
RDFグラフはリテラルの主語を含まないかもしれないため、リテラルを主語として持つ任意のSPARQLトリプル・パターンは、どんなRDFグラフにもマッチしないでしょう。
プロパティー・パスは、n = length(ST)-1の場合に、i=0 to nについて、tiの目的語がti+1の主語と同じ用語であるような、シーケンスSTのtiのトリプルのシーケンスです。
t0の主語をパスの始点と呼びます。
tnの目的語をパスの終点と呼びます。
個々のtiがGのトリプルである場合、プロパティー・パスはグラフGのパスです。
プロパティー・パスの範囲は、データセット内の複数のグラフには及びません。
プロパティー・パス式は、上記のプロパティー・パス形式を用いた式です。
PPをすべてのプロパティー・パス式の集合とします。プロパティー・パス・パターンは、以下の集合のメンバーです。
(RDF-T ∪ V) x PP x (RDF-T ∪ V)
プロパティー・パス・パターンは、プロパティー・パス式をプロパティー・ポジションに含めるために、トリプル・パターンを一般化したものです。
ソリューション・マッピングは、1組の変数から1組のRDF用語へのマッピングです。我々は、それが明確である場合に「ソリューション」という用語を使用します。
ソリューション・シーケンスは、ソリューションのリストで、順不同でありえます。
μから得られた変数に対する用語を用いて、式exprの値に対するexpr(μ)を記述します。評価は、エラーになるかもしれません。
ソリューション・シーケンス修飾子は、次のうちの1つです。
この項は、SPARQLクエリ文字列内のグラフ・パターンとソリューション修飾子をSPARQL代数式に変換するプロセスを定義します。 記述したプロセスは、1つのクエリの入れ子のレベルを変換し、入れ子のSELECT構文を用いてサブクエリによって生成される際に、サブクエリ上で再帰的に適用されます。個々のレベルは、グラフ・パターン・マッチングとフィルタリングで構成され、その後に、ソリューション修飾子のアプリケーションが続きます。
SPARQLクエリ文字列が分析され、4項で示したIRIとトリプル・パターンの省略形が適用されます。現時点では、抽象構文木は、以下で構成されています。
パターン | 修飾子 | クエリ形式 | その他 |
---|---|---|---|
RDF terms | DISTINCT | SELECT | VALUES |
Property path expression | REDUCED | CONSTRUCT | SERVICE |
Property path patterns | Projection | DESCRIBE | |
Groups | ORDER BY | ASK | |
OPTIONAL | LIMIT | ||
UNION | OFFSET | ||
GRAPH | Select expressions | ||
BIND | |||
GROUP BY | |||
HAVING | |||
MINUS | |||
FILTER |
このような抽象構文木を変換した結果は、次の表の符号をSPARQL代数で用いるSPARQLクエリです。
グラフ・パターン | ソリューション修飾子 | プロパティー・パス |
---|---|---|
BGP | ToList | PredicatePath |
Join | OrderBy | InversePath |
LeftJoin | Project | SequencePath |
Filter | Distinct | AlernativePath |
Union | Reduced | ZeroOrMorePath |
Graph | Slice | OneOrMorePath |
Extend | ToMultiSet | ZeroOrOnePath |
Minus | NegatedPropertySet | |
Group | ||
Aggregation | ||
AggregateJoin |
Sliceは、OFFSETとLIMITを組み合わせたものです。
ToListはグラフ・パターン・マッチングの結果からシーケンスへの変換が起こる場合に用いられます。
ソリューション・シーケンスから多重集合への変換が生じる場合には、ToMultiSetが用いられます。
このドキュメントでは、SPARQL代数をクエリに対して実行する際に、変換がその時点でのソリューション・マッピングの定義域内に存在していれば、変数は範囲内であると定義します。下記の定義では、クエリの抽象構文からこれを判断する方法を示しています。
射影を持つサブクエリが変数を見えなくできることに注意してください。FILTER
またはMINUS
の変数を用いても、変数がそれらの形式の外部で範囲内になることはありません。
P、P1、P2がグラフ・パターンであり、E、E1、,...Enが式であるとします。以下のとき、変数v
は範囲内です。
構文形式 | 範囲内の変数 |
---|---|
Basic Graph Pattern (BGP) | v はBGPで発生する。 |
Path | v はパスで発生する。 |
Group { P1 P2 ... } |
v が、1以上のP1、P2で範囲内にあれば、それは範囲内 |
GRAPH term { P } |
v は用語(term )、または、v はPにおいて範囲内 |
{ P1 } UNION { P2 } |
v はP1において範囲内、または、P2において範囲内 |
OPTIONAL {P} |
v はPにおいて範囲内 |
SERVICE term {P} |
v は用語(term )、または、v はPにおいて範囲内 |
BIND (expr AS v) |
v は範囲内 |
SELECT .. v .. { P } |
v は範囲内 |
SELECT ... (expr AS v) |
v は範囲内 |
GROUP BY (expr AS v) |
v は範囲内 |
SELECT * { P } |
v はP において範囲内 |
VALUES v { values } |
v は範囲内 |
VALUES varlist { values } |
v がvarlist にあれば、v は範囲内 |
変数vは、(expr AS v)
形式の部分では範囲内でありえません。(expr AS v)
の範囲は、SELECT
式で即座に適用されます。
BINDでは、(expr AS v)
は、変数v
が、それが用いられているグループ・グラフ・パターン内の先行する要素の範囲内にはない必要があります。
SELECT
では、変数v
はSELECT句のグラフ・パターンにおいて範囲内であってはならず、その句の中で選択した別の式において使用済みであってもなりません。
この項では、SPARQLグラフ・パターンをSPARQL代数式に置換するプロセスについて述べます。このプロセスは、グループ・グラフ・パターン({...}
区切り記号間の単位)に適用され、クエリのWHERE
句を生成し、再帰的にグループ・グラフ・パターン内の個々の構文要素に適用されます。置換の結果は、SPARQL代数式です。
要約すると、次のステップで適用されます。
FILTER
をまとめる。このドキュメントでは、グラフ・パターンを置換するためにここで記述しているリズムに対し、
translate(graph pattern)
と記述します。
OPTIONAL { { ... FILTER ( ... ?x ... ) } }.
.
次の2つの規範的でないテストケースでこれを例証します。
グラフ・パターンのすべての置換の後に単純化のステップを適用するのが望ましいです。
4項で示したIRIとトリプル・パターンの省略形を展開します。
FILTER
要素の集約FILTER
式は、それが出現するグループ・グラフ・パターンの全体に適用されます。フィルタリングを行なう代数演算子は、個々のグループ要素の置換の後にグループに加えられます。ここでフィルタをまとめ、それをグループから除外し、その後で、置換されたグループ・グラフ・パターンの全体にそれを適用します。
このステップで、EXISTS
とNOT EXISTS
というFILTER式のグラフ・パターンも置換します。
Let FS := empty set For each form FILTER(expr) in the group graph pattern: In expr, replace NOT EXISTS{P} with fn:not(exists(translate(P))) In expr, replace EXISTS{P} with exists(translate(P)) FS := FS ∪ {expr} End
フィルタ式の集合FS
は、後で使用します。
下記の表は、SPARQL構文からSPARQL代数の用語へのプロパティー・パス式の置換を示しています。これは、プロパティー・パス式のすべての要素に再帰的に適用されます。
この後の、次のステップは、ある形式をトリプル・パターンに置換し、それは後で、隣接(グループ・パターン区切り記号である{と}が間に入らない)または他の構文形式により、基本グラフ・パターンに変換されます。全体として、単なる1つのIRIのSPARQL構文プロパティー・パスは、フック数のトリプル・パターンになり、それらは基本グラフ・パターンに集約されます。
注意:
次の符号を導入しています。
構文形式(パス) | 代数(パス) |
---|---|
iri |
link(iri) |
^path |
inv(path) |
!(:iri1|...|:irin) |
NPS({:iri1 ... :irin}) |
!(^:iri1|...|^:irin) |
inv(NPS({:iri1 ... :irin})) |
!(:iri1|...|:irii|^:irii+1|...|^:irim) ? |
alt(NPS({:iri1 ...:irii}),
|
path1 / path2 |
seq(path1, path2) |
path1 | path2 |
alt(path1, path2) |
path* |
ZeroOrMorePath(path) |
path+ |
OneOrMorePath(path) |
path? |
ZeroOrOnePath(path) |
前のステップでは、プロパティー・パス式を置換しました。このステップでは、プロパティー・パス・パターン(主語エンドポイント、プロパティー・パス式、目的語エンドポイント)をトリプル・パターンに置換するか、パス評価のための一般的な代数の操作にラップします。
注意:
Path(...)
という一般的な形式を用いるために、任意の残りのプロパティー・パス式をシンプルにラップします。代数(パス) | 置換 |
---|---|
X link(iri) Y |
X iri Y |
X inv(iri) Y |
Y iri X |
X seq(P, Q) Y |
X P ?V . ?V Q P |
X P Y |
Path(X, P, Y) |
全体的なパス置換プロセスの例(?_V
は、新しい変数):
次に、置換プロセスを再帰的に適用し、個々の残りのグラフ・パターン形式を置き換えます。
形式が
GroupOrUnionGraphPattern
の場合
A := 未定義とします。 For each element G in the GroupOrUnionGraphPattern If A is undefined A := Translate(G) Else A := Union(A, Translate(G)) End 結果はA
形式が
GraphGraphPattern
の場合
形式がGRAPH IRI GroupGraphPatternであれば、 結果はGraph(IRI, Translate(GroupGraphPattern))
形式がGRAPH Var GroupGraphPatternであれば、 結果はGraph(Var, Translate(GroupGraphPattern))
形式が
GroupGraphPattern
の場合
S := 空の集合とします。 G := 空のパターン、空の集合である基本グラフ・パターンとします。 For each element E in the GroupGraphPattern If E is of the form OPTIONAL{P} A := Translate(P)とし、 If A is of the form Filter(F, A2) G := LeftJoin(G, A2, F) Else G := LeftJoin(G, A, true) End End If E is of the form MINUS{P} G := Minus(G, Translate(P)) End If E is of the form BIND(expr AS var) G := Extend(G, var, expr) End If E is any other form Let A := Translate(E) G := Join(G, A) End End 結果はGです。
形式がInlineDataの場合
結果はソリューション・マッピング「データ」の多重集合です。
データは、複数の変数(または、1つの変数)のリストにおいて対応する位置にある変数からソリューション・マッピングを作成することで作成され、BindingValue
が単語UNDEF
であれば、バインディングを削除します。
形式がSubSelectの場合
結果はToMultiset(Translate(SubSelect))
書き換えの例の2番目の形式は、1番目のものに単純化のステップで削除した空のグループのjoinを付けたものです。
例: 1つのトリプル・パターンから成る1つの基本グラフ・パターンを持つグループ
例: 2つのトリプル・パターンから成る1つの基本グラフ・パターンを持つグループ
例: 2つの基本グラフ・パターンの和集合から成るグループ
例: 1つの和集合と1つの基本グラフ・パターンの和集合から成るグループ
例: 1つの基本グラフ・パターンと1つのオプションのグラフ・パターンから成るグループ
例: 1つの基本グラフ・パターンと2つのオプションのグラフ・パターンから成るグループ
例: 1つの基本グラフ・パターンとフィルタを持つ1つのオプションのグラフ・パターンから成るグループ
例: 1つの和集合のグラフ・パターンと1つのオプションのグラフ・パターンから成るグループ
例: 1つの基本グラフ・パターン、1つのフィルタ、および1つのオプションのグラフ・パターンから成るグループ
例: BINDを含むパターン
例: BINDを含むパターン
例: MINUSを含むパターン
例: サブクエリを含むパターン
このステップでは、次の順にクエリ・レベルの句を処理します。
ステップ: GROUP BY
GROUP BY
キーワードを用いている場合や、射影で集約を用いることにより暗黙的なグルーピングが存在する場合には、グループ関数によってグルーピングが行なわれます。これにより、ソリューションの集合は、全体的に同じカーディナリティーを持つ、1つ以上のソリューションのグループに分割されます。暗黙的なグルーピングの場合では、固定定数(1)を用いて、すべてのソリューションを一つのグループにグループ化します。
ステップ: 集約
集約のステップは、クエリ・レベルで変換として適用され、クエリ・レベルの集約式をAggregation()代数式に置換します。
集約を用いたクエリ・レベルの変換は、次のようになります。
Let A := the empty sequence Let Q := the query level being evaluated Let P := the algebra translation of the GroupGraphPattern of the query level Let E := [], a list of pairs of the form (variable, expression) If Q contains GROUP BY exprlist Let G := Group(exprlist, P) Else If Q contains an aggregate in SELECT, HAVING, ORDER BY Let G := Group((1), P) Else skip the rest of the aggregate step End Global i := 1 # Initially 1 for each query processed For each (X AS Var) in SELECT, each HAVING(X), and each ORDER BY X in Q For each unaggregated variable V in X Replace V with Sample(V) End For each aggregate R(args ; scalarvals) now in X # note scalarvals may be omitted, then it's equivalent to the empty set Ai := Aggregation(args, R, scalarvals, G) Replace R(...) with aggi in Q i := i + 1 End End For each variable V appearing outside of an aggregate Ai := Aggregation(V, Sample, {}, G) E := E append (V, aggi) i := i + 1 End A := Ai, ..., Ai-1 P := AggregateJoin(A)
注: aggiは一時変数です。Eは、その後、18.2.4.4のselect式の処理に用いられます。
例:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> SELECT (SUM(?val) AS ?sum) (COUNT(?a) AS ?count) WHERE { ?a rdf:value ?val . } GROUP BY ?a
SUM式はagg1になり、COUNT式はagg2になります。
Let G := Group((?a), BGP(?a rdf:value ?val)) A1 = Aggregation((?val), Sum, {}, G) A2 = Aggregation((?a), Count, {}, G) A := (A1, A2) Let P := AggregateJoin(A)
HAVING式は、FILTER()と同じ規則を用いて評価されます。HAVING句が評価されるロジック・ポジションのため、SELECT句によって射影された式がHAVING句では表示されないことに注意してください。
Let Q := the query level being evaluated Let P := the algebra translation of the query level so far For each HAVING(E) in Q P := Filter(E, P) End
クエリに、後続するVALUES句がある場合:
Let P := the algebra translation of the query level so farP := Join(P, ToMultiSet(data)) where data is a solution sequence formed from the VALUES clause
データの置換は、インライン・データのものと同じです。
ステップ: Select式
考慮すべき抽象構文の形式が2つあります。
SELECT selItem ... { pattern } SELECT * { pattern }
Let X := algebra from earlier steps
Let VS := list of all variables visible in the pattern,
so restricted by sub-SELECT projected variables and GROUP BY variables.
Not visible: only in filter, exists/not exists, masked by a subselect,
non-projected GROUP variables, only in the right hand side of MINUS
Let PV := {}, a set of variable names
Note, E is a list of pairs of the form (variable, expression), defined in section 18.2.4
If "SELECT *"
PV := VS
If "SELECT selItem ...
:"
For each selItem:
If selItem is a variable
PV := PV ∪ { variable }
End
If selItem is (expr AS variable)
variable must not appear in VS nor in PV; if it does then generate a syntax error and stop
PV := PV ∪ { variable }
E := E append (variable, expr)
End
End
For each pair (var, expr) in E
X := Extend(X, var, expr)
End
Result is X
The set PV is used later for projection.
変数がSELECTのWHERE句の中で用いられていたり、このSELECT式の中でASのターゲットとして既に用いられている場合には、AS(例えば... AS? x)の名前付きターゲットとして変数を用いると構文エラーが発生します。
ソリューション修飾子は、パターン・マッチングの後でSPARQLクエリの処理に適用します。ソリューション修飾子は、次の順序でクエリに適用されます。
ステップ: ToList
ToListは、多重集合を、同じ要素とカーディナリティーを持つシーケンスに変えます。シーケンスに対する暗黙的な順序付けはありません。同じものが隣接している必要はありません。
Let M := ToList(Pattern)
射影変数の集合であるPV
は、SELECT式の処理において算出されました。
M := Project(M, PV)
ここでは、varsは、SELECT句で記述された変数の集合であるか、SELECT *が用いられた場合には、クエリ中で範囲内にあるすべての名前付き変数です。
グラフ・パターンをマッチさせるときには、可能なソリューションは、バッグ(bag)としても知られている多重集合[multiset]を形成します。多重集合は、各要素が1回以上出現しうる要素の順不同のコレクションです。これは、多重集合内の集合の各要素の出現回数を示す、1組の要素とカーディナリティー関数で記述されます。
ソリューション・マッピングを、μと記述する。
dom(μ0)が空の集合であるようなマッピングを、μ0と記述します。
カーディナリティー1を持つ、空のマッピングμ0,からきっかり成る多重集合を、Ω0と記述します。これは、joinと同値です。
RDF用語t : { (x, t) }に対するソリューション・マッピング変数xを、μ(x)と記述します。
きっかりμ(?x->t)から成る多重集合、つまり、カーディナリティー1を持つ{ { (x, t) } }を、Ω(x)と記述します。
2つのソリューション・マッピングμ1とμ2は、dom(μ1)およびdom(μ2)のすべての変数vに対し、μ1(v) = μ2(v)である場合、互換性があります。
Here, μ1(v) = μ2(v) means that μ1(v) and μ2(v) are the same RDF term.
μ1とμ2に互換性がある場合、μ1 ∪ μ2もマッピングです。μ1 ∪ μ2を、merge(μ1, μ2)と記述します。
マッピングΩの多重集合におけるソリューション・マッピングμのカーディナリティーを、card[Ω](μ)と記述します。
基本グラフ・パターンは、クエリの当該部分に対するアクティブ・グラフにマッチングします。変数と空白ノードの両方を用語に置き換えることによって、インスタンスの2つの概念を示し、基本グラフ・パターンをインスタンス化できます。空白ノードは、RDFインスタンス・マッピングσを用いて空白ノードからRDF用語に置き換えられ、変数は、ソリューション・マッピングによってクエリ変数からRDF用語に置き換えられます。
パターン・インスタンス・マッピングPは、RDFインスタンス・マッピングσとソリューション・マッピングμの組み合わせです。 P(x) = μ(σ(x))
BGP「x」の場合、P(x)は、σが定義されているxの空白ノードbとσ(b)とを入れ替え、μが定義されているxのすべての変数vとμ(v)とを入れ替えた結果を示します。
任意のパターン・インスタンス・マッピングは、それぞれクエリ変数と空白ノードに制限することによって得られた、ユニークなソリューション・マッピングおよびユニークなRDFインスタンス・マッピングを定義します。
BGPを基本グラフ・パターンとし、GをRDFグラフとします。
P(BGP)がGのサブグラフであり、μがBGPのクエリ変数に対するPの制限であるような、パターン・インスタンス・マッピングPがあるとき、μは、GからのBGPのソリューションです。
card[Ω](μ) = card[Ω](P = μ(σ) であるような異なるRDFインスタンス・マッピングの数、σはパターン・インスタンス・マッピングであり、P(BGP)はGのサブグラフです)。
基本グラフ・パターンが空の集合である場合、ソリューションはΩ0です。
この定義によって、ソリューション・マッピングは、基本グラフ・パターンであるBGPの変数をGの空白ノードにバインドできます。SPARQLは、結果フォーマットのドキュメント(SPARQLクエリ結果XMLフォーマット、SPARQL 1.1クエリ結果JSONフォーマット、SPARQL 1.1クエリ結果CSVおよびTSVフォーマット)の空白ノード識別子をそのドキュメントに対して有効であるものとして扱うため、データセットのアクティブ・グラフにおけるノードを識別しているとは解釈されませんしたがって、DSがクエリのデータセットである場合、パターンのソリューションはDS自身のアクティブ・グラフからのものではなくRDFグラフからのものであると解釈され、これはスコーピング・グラフと呼ばれ、DSのアクティブ・グラフに対しグラフ同等(graph-equivalent)であるけれどもDSまたはBGPと空白ノードを共有しません。スコーピング・グラフは、1つのクエリに対するすべてのソリューションに用いられます。スコーピング・グラフは、純粋に理論的構成概念(theoretical construct)で、実際には、単なる空白ノード識別子に対するドキュメント範囲の慣習によって効果が得られます。
RDFの空白ノードが多くのパターンに対する多くの重複するソリューションを無限に許すため、多くのパターンのソリューション(空白ノードを別の空白ノードに置き換えることによって得られる)が無限に存在しえます。したがって、何らかの形で基本グラフ・パターンのソリューションを区切る必要があります。SPARQLは、基本グラフ・パターンのソリューションを決定するために、サブグラフ・マッチの基準を用います。基本グラフ・パターンからアクティブ・グラフのサブセットにマッピングする異なるパターンのインスタンスに対し、それぞれ1つのソリューションが存在します。
これは、重複の排除よりむしろ計算の容易さのために最適化されます。これによって、データセットのアクティブ・グラフが貧弱であるときでも、クエリ結果に重複を含むことができ、論理的に同等なデータセットが異なるクエリ結果を出すことが可能になります。
この項では、プロパティー・パス・パターンの評価について定義します。プロパティー・パス・パターンは、主語エンドポイント(RDF用語または変数)、プロパティー・パス式および目的語エンドポイントです。プロパティー・パス式の置換は、長さ1のプロパティー・パスをトリプル・パターンに変換するなど、ある形式を他のSPARQL式に変換し、これは次に基本グラフ・パターンにまとめられます。これによって、ZeroOrOnePath、ZeroOrMorePath、OneOrMorePath、NegatedPropertySetsというプロパティー・パス・オペレーターと、さらに、これらのオペレーター内に含まれているパス式が残ります。
すべの残りのプロパティー・パス式は、エンドポイントのXとYに対し、Path(X, path, Y)
という形式で代数内にあります。例えば、(:p/:q)*
という構文は、ZeroOrMorePath式で、シーケンス・プロパティー・パスを伴い、ZeroOrMorePath(seq(link(:p), link(:q)))
という代数式になります。
プロパティー・パス・パターンの評価の場合、
eval(Path(X, PP, Y))
と記述します。これによって、ソリューション・マッピングμの多重集合が作成され、個々のソリューション・マッピングは、使用されている変数のバインディングを持っています(XとYはそれぞれ、変数になりえる)。一部の演算子は、1つのソリューション・マッピングの集合を作成するだけです。
x1, x2, ..., xn
の変数の場合、
と記述します。
次のように記述します。
x:term |
x がRDF用語の場合 |
x:var |
x が変数の場合 |
x:path |
x がパス式の場合 |
すべての評価は、全体のクエリ評価において、その時点のアクティブ・グラフとのマッチングにより行なわれます。明確にするために、個々の定義へのアクティブ・グラフの組み込みを明示的に省略しています。
定義: 述語プロパティー・パスの評価
IRI iriを用いた、パス(X, link(iri), Y)を述語逆プロパティー・パス・パターンとします。
eval(Path(X, link(iri), Y)) = 基本グラフ・パターンの評価 {X iri Y}
XとYの両方が変数ならば、これは次と同じです。
Xが変数で、YがRDF用語である場合、
XがRDF用語で、Yが変数である場合、
XとYの両方がRDF用語である場合、
非形式的には、述語プロパティ・パスの評価は、クエリ評価において、その時点のサブクエリSELECT * { X P Y }
を実行するのと同じことです。
PとQをプロパティー・パス式とします。Vを新たな変数とします。
A = Join( eval(Path(X, P, V)), eval(Path(V, Q, Y)) )eval(Path(X, seq(P,Q), Y)) = Project(A, Var(X,Y))
非形式的には、これは次と同じです。
SELECT * { X P _:a . _:a Q Y }
これは、空白ノード_:a
は、それがSELECT *
の結果に出現しない場合を除いて、変数のように機能する(シンプルな含意において)という事実を用いています。
定義: 代替プロパティー・パスの評価
PとQをプロパティー・パス式とします。
eval(Path(X, alt(P,Q), Y)) = Union(eval(Path(X, P, Y)), eval(Path(X, Q, Y)))
非形式的には、これは次と同じです。
SELECT * { { X P Y } UNION { X Q Y } }
定義: グラフのノード集合
グラフGのノード集合、nodes(G)は、次の通りです。
nodes(G) = { n | n is an RDF term that is used as a subject or object of a triple of G}
定義: ZeroOrOnePathの評価
eval(Path(X:term, ZeroOrOnePath(P), Y:var)) = { (Y, yn) | yn = X or {(Y, yn)} in eval(Path(X,P,Y)) }
eval(Path(X:var, ZeroOrOnePath(P), Y:term)) = { (X, xn) | xn = Y or {(X, xn)} in eval(Path(X,P,Y)) }
eval(Path(X:term, ZeroOrOnePath(P), Y:term)) = { {} } if X = Y or eval(Path(X,P,Y)) is not empty { } othewise
eval(Path(X:var, ZeroOrOnePath(P), Y:var)) = { (X, xn) (Y, yn) | either (yn in nodes(G) and xn = yn) or {(X,xn), (Y,yn)} in eval(Path(X,P,Y)) }
このドキュメントでは、ZeroOrMorePathとOneOrMorePathの定義で用いられる補助関数(ALP)を定義しています。ここで示しているアルゴリズムが機能を指定する役割を果たすをことに注意してください。実装では、全体としてクエリに対して同じ結果を生むあらゆる方法による評価を自由に実行することができます。ZeroOrMorePathとOneOrMorePathの形式は、パスによって結合されている別々のノードに基づいて、マッチを返します。
マッチング・アルゴリズムは、すべてのパスをたどることを基礎としており、パス上でグラフ・ノード(主語または目的語)が訪問済みである場合に検知します。
非形式的には、このアルゴリズムは、パスの1つのアプリケーションによって、ステップごとに結果の多重集合を拡張しようと試み、この特定のパスのどのノードを既に訪問したかを指摘します。検討中のパスをノードが既に訪問していれば、それは、別のステップの候補になりません。
定義: 関数ALP
Let eval(x:term, path) be the evaluation of 'path', starting at RDF term x, and returning a multiset of RDF terms reached by repeated matches of path. ALP(x:term, path) = Let V = empty multiset ALP(x:term, path, V) return is V # V is the set of nodes visited ALP(x:term, path, V:set of RDF terms) = if ( x in V ) return add x to V X = eval(x,path) For n:term in X ALP(n, path, V) End
定義: ZeroOrMorePathの評価
eval(Path(X:term, ZeroOrMorePath(path), vy:var)) = { { (vy, n) } | n in ALP(X, path) } eval(Path(vx:var, ZeroOrMorePath(path), vy:var)) = { { (vx, t), (vy, n) } | t in nodes(G), (vy, n) in eval(Path(t, ZeroOrMorePath(path), vy)) } eval(Path(vx:var, ZeroOrMorePath(path), y:term)) = eval(Path(y:term, ZeroOrMorePath(inv(path)), vx:var)) eval(Path(x:term, ZeroOrMorePath(path), y:term)) = { { } } if { (vy:var,y) } in eval(Path(x, ZeroOrMorePath(path) vy) { } otherwise
定義: OneOrMorePathの評価
eval(Path(X, OneOrMorePath(path), Y))
# For OneOrMorePath, we take one step of the path then start # recording nodes for results. eval(Path(x:term, OneOrMorePath(path), vy:var)) = Let X = eval(x, path) Let V = the empty multiset For n in X ALP(n, path, V) End result is V eval(Path(vx:var, OneOrMorePath(path), vy:var)) = { { (vx, t), (vy, n) } | t in nodes(G), (vy, n) in eval(Path(t, OneOrMorePath(path), vy)) } eval(Path(vx:var, OneOrMorePath(path), y:term)) = eval(Path(y:term, OneOrMorePath(inv(path)), vx)) eval(Path(x:term, OneOrMorePath(path), y:term)) = { { } } if { (vy:var, y) } in eval(Path(x, OneOrMorePath(path), vy)) { } otherwise
Write μ' as the extension of a solution mapping: μ'(μ,x) = μ(x) if x is a variable μ'(μ,t) = t if t is a RDF term
Let x and y be variables or RDF terms, and S a set of IRIs: eval(Path(x, NPS(S), y)) = { μ | ∃ triple(μ'(μ,x), p, μ'(μ,y)) in G, such that the IRI of p ? S }
SPARQLの抽象クエリに内の残りの各シンボルに対し、評価のための演算子を定義しています。同じ名前のSPARQL代数演算子は、「評価セマンティクス」の項で記述されているように、SPARQLの抽象クエリ・ノードを評価するために用いられます。基本グラフ・パターントプロパティー・パス・パターンの評価は、上で記述しました。
定義: Filter
Ωをソリューション・マッピングの多重集合とし、exprを式とします。次のとおり定義します。
Filter(expr, Ω, D(G)) = { μ | μ in Ω and expr(μ) is an expression that has an effective boolean value of true }
card[Filter(expr, Ω, D(G))](μ) = card[Ω](μ)
Note that evaluating an exists(pattern)
expression uses the dataset and active graph, D(G).
See the evaluation of filter.
定義: Join
Ω1とΩ2をソリューション・マッピングの多重集合とします。次のとおり定義します。
Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 in Ω1and μ2 in Ω2, and μ1 and μ2 are compatible }
card[Join(Ω1, Ω2)](μ) =
for each merge(μ1, μ2), μ1
in Ω1and μ2 in Ω2 such that μ = merge(μ1, μ2),
sum over (μ1, μ2), card[Ω1](μ1)*card[Ω2](μ2)
Joinにおけるソリューション・マッピングμは、異なるソリューション・マッピング、結合された多重集合におけるμ1とμ2において出現することは可能です。μのカーディナリティーは、すべての可能性のカーディナリティーの合計です。
定義: Diff
Ω1とΩ2をソリューション・マッピングの多重集合とし、exprを式とします。次のとおり定義します。
Diff(Ω1, Ω2, expr) = { μ | μ in Ω1 such that ∀ μ′ in Ω2, either μ and μ′ are not compatible or μ and μ' are compatible and expr(merge(μ, μ')) has an effective boolean value of false }
card[Diff(Ω1, Ω2, expr)](μ) = card[Ω1](μ)
Diffは、LeftJoinの定義のために内部的に使用されます。
定義: LeftJoin
Ω1とΩ2をソリューション・マッピングの多重集合とし、exprを式とします。次のとおり定義します。
LeftJoin(Ω1, Ω2, expr) = Filter(expr, Join(Ω1, Ω2)) ∪ Diff(Ω1, Ω2, expr)
card[LeftJoin(Ω1, Ω2, expr)](μ) = card[Filter(expr, Join(Ω1, Ω2))](μ) + card[Diff(Ω1, Ω2, expr)](μ)
これは、完全形で記述すれば、次の通りです。
LeftJoin(Ω1, Ω2, expr) =
{ merge(μ1, μ2) | μ1 in Ω1 and μ2 in Ω2, μ1 and μ2 are compatible and expr(merge(μ1, μ2)) is true }
∪
{ μ1 | μ1 in Ω1, ∀ μ2 in Ω2, μ1 and μ2 are not compatible, or Ω2 is empty }
∪
{ μ1 | μ1 in Ω1, ∃ μ2 in Ω2, μ1 and μ2 are compatible and expr(merge(μ1, μ2)) is false. }
これらが異なっているため、LeftJoinのカーディナリティーは、定義のこれらの個々の構成要素のカーディナリティーです。
定義: Union
Ω1とΩ2をソリューション・マッピングの多重集合とします。次のとおり定義します。
Union(Ω1, Ω2) = { μ | μ in Ω1 or μ in Ω2 }
card[Union(Ω1, Ω2)](μ) = card[Ω1](μ) + card[Ω2](μ)
定義: Minus
Ω1とΩ2をソリューション・マッピングの多重集合とします。次のとおり定義します。
Minus(Ω1, Ω2) = { μ | μ in Ω1 . ∀ μ' in Ω2, either μ and μ' are not compatible or dom(μ) and dom(μ') are disjoint }
card[Minus(Ω1, Ω2)](μ) = card[Ω1](μ)
dom(μ)とdom(μ')には制限が追加されています。なぜならば、そうでない場合、Ω1のソリューション・マッピングと同様に変数を持っていないΩ2にソリューション・マッピングがあれば、Minus(Ω1, Ω2)は、残りのΩ2にかかわらず、空になるだろうからです。空のソリューション・マッピングは、他のすべてのソリューション・マッピングと互換性があります。したがって、そうでない場合、P MINUS {}
は任意のパターンP
に対し空でしょう。
μをソリューション・マッピングとし、Ωをソリューション・マッピングの多重集合とし、varを変数とし、exprを式とします。次のとおり定義します。
Extend(μ, var, expr) = μ ∪ { (var,value) | var not in dom(μ) and value = expr(μ) }
Extend(μ, var, expr) = μ if var not in dom(μ) and expr(μ) is an error
Extend is undefined when var in dom(μ).
Extend(Ω, var, expr) = { Extend(μ, var, expr) | μ in Ω }
Cがxの条件である場合、要素のシーケンスに対し[ x | C ]と書きます。
Lでのxというカーディナリティーになるように、card[L](x)と書きます。
Ωをソリューション・マッピングの多重集合とします。次のとおり定義します。
ToList(Ω) = a sequence of mappings μ in Ω in any order, with card[Ω](μ) occurrences of μ
card[ToList(Ω)](μ) = card[Ω](μ)
Ψをソリューション・マッピングのシーケンスとします。次のとおり定義します。
OrderBy(Ψ, condition) = [ μ | μ in Ψ and the sequence satisfies the ordering condition]
card[OrderBy(Ψ, condition)](μ) = card[Ψ](μ)
Ψをソリューション・マッピングのシーケンスとし、PVを変数の集合とします。
マッピングμに対し、PVの変数に対するμの制限になるようにProj(μ, PV)を記述します。
Project(Ψ, PV) = [ Proj(Ψ[μ], PV) | μ in Ψ ]
card[Project(Ψ, PV)](μ) = card[Ψ](μ)
Project(Ψ, PV)の順序は、OrderByによって与えられた順序付けを保持しなければなりません。
Ψをソリューション・マッピングのシーケンスとします。次のとおり定義します。
Distinct(Ψ) = [ μ | μ in Ψ ]
card[Distinct(Ψ)](μ) = 1
Distinct(Ψ)の順序は、OrderByによって与えられた順序付けを保持しなければなりません。
Ψをソリューション・マッピングのシーケンスとします。次のとおり定義します。
Reduced(Ψ) = [ μ | μ in Ψ ]
card[Reduced(Ψ)](μ) is between 1 and card[Ψ](μ)
Reduced(Ψ)の順序は、OrderByによって与えられた順序付けを保持しなければなりません。
Reducedソリューション・シーケンス修飾子は、定義済みのカーディナリティーを保証しません。
Ψをソリューション・マッピングのシーケンスとします。次のとおり定義します。
Slice(Ψ, start, length)[i] = Ψ[start+i] for i = 0 to (length-1)
Ψをソリューション・シーケンスとします。次のとおり定義します。
ToMultiSet(Ψ) = { μ | μ in Ψ }
card[ToMultiSet(Ψ)](μ) = card[Ψ](μ)
ListEvalは、ソリューションに対する式のリストを評価し、結果の値のリストを返すために用いられる関数です。
ToMultisetは、シーケンスを、シーケンスと同じ要素とカーディナリティーを持つ多重集合に変えます。シーケンスの順序は結果として生成される多重集合には影響がなく、重複は保持されます。
定義: Exists
exists(pattern)は、評価時に現在のソリューション・マッピングとアクティブ・グラフを与えられた場合に、パターンの評価結果が空でないソリューション・シーケンスになる場合に真(true)を返し、そうでなければ偽(false)を返す関数です。
グループは、ソリューションの属性に基づいて、1つのソリューション・シーケンスを複数のソリューションにグループ化する関数です。
グループは、式のリストをソリューション・シーケンスに対して評価し、ソリューション・シーケンスに対してキーから部分関数の集合を生成します。
Group(exprlist, Ω) = { ListEval(exprlist, μ) → { μ' | μ' in Ω, ListEval(exprlist, μ) = ListEval(exprlist, μ') } | μ in Ω }
定義: ListEval
ListEval((expr1, ..., exprn), μ) returns a list (e1, ..., en), where ei = expri(μ) or error.
ListEvalは、リスト要素の評価の結果として生じるエラーを保持します。
ListEvalの結果はエラーでありえますが、エラーはグループ化するために使用でき、エラー価値を含んでいるソリューションは射影の際に削除されることに注意してください。
バインドされていない式の評価がエラーであるとき、ListEval((unbound), μ) = (error)。
集約は、集約式の出力としてスカラー値を計算する関数です。これは、SELECT句、HAVING評価プロセス、およびORDER BY(必要な場合)で用いられます。集約は、集合関数を用いて、ソリューションのグループに対する集約された値を計算します。
exprlistを式または*のリストとし、funcを集合関数とし、scalarvalsをクエリの集約から渡された部分関数の集合(恐らく空)とし、{ key1→Ω1, ..., keym→Ωm}を、グループ化のステップによって生成されるキーからソリューション・シーケンスへの部分関数の多重集合とします。
集約は、与えられた多重集合に集合関数funcを適用し、キーおよびそのキーに対するソリューションのパーティションごとに、1つの値を生成します。
Aggregation(exprlist, func, scalarvals, { key1→Ω1, ..., keym→Ωm } )
= { (key, F(Ω)) | key → Ω in { key1→Ω1, ..., keym→Ωm } }
where
M(Ω) = { ListEval(exprlist, μ) | μ in Ω }
F(Ω) = func(M(Ω), scalarvals), for non-DISTINCT
F(Ω) = func(Distinct(M(Ω)), scalarvals), for DISTINCT
特例: COUNT
を*
という式と共に用いた場合、Fの値は、グループ・ソリューション・シーケンスである、card[Ω]
になるか、DISTINCT
キーワードが存在する場合にはcard[Distinct(Ω)]
のカーディナリティーになるでしょう。
scalarvalsは、基礎となる集合機能に値を渡し、グルーピングの仕組みを迂回するために用いられます。例えば、GROUP_CONCAT(?x ; separator="|")
という集約式には、{ "separator" → "|" }というscalarvals引数があります。
すべての集約は、その引数リストの最初のトークンとしてDISTINCT
キーワードを持つことができます。このキーワードが存在すれば、funcに対する最初の引数はDistinct(M)です。
例
次の値を持つソリューション多重集合(Ω)の場合、
ソリューション | ?x | ?y | ?z |
μ1 | 1 | 2 | 3 |
μ2 | 1 | 3 | 4 |
μ3 | 2 | 5 | 6 |
そして、クエリ式SELECT (ex:agg(?y, ?z) AS ?agg) WHERE { ?x ?y ?z } GROUP BY ?xです。
G = Group((?x), Ω) = { ( (1), { μ1, μ2 } ), ( (2), { μ3 } ) }を生成します。
したがって、Aggregation((?y, ?z), ex:agg, {}, G) =
{ ((1), eg:agg({(2, 3), (3, 4)}, {})), ((2), eg:agg({(5, 6)}, {})) }です。
定義: AggregateJoin
S1, ..., Snを集合のリストとします。その場合、個々の集合であるSiは、集約によって生成される際に、値マップに対する(集約された)キーを含んでいます。
Let K = { key | key in dom(Sj) for some 1 <= j <= n } be the set of keys, then
AggregateJoin(S1, ..., Sn) = { agg1→val1, ..., aggn→valn | key in K and key→vali in Si for each 1 <= i <= n }
Flattenは、リストの多重集合を1つの多重集合に平坦化する(collapse)ために使用される関数です。したがって、例えば、{ (1, 2), (3, 4) }は、{ 1, 2, 3, 4 }になります。
定義: Flatten
Flatten(M)関数は、M {(L1, L2, ...), ...}というリストの多重集合を取り、{ x | L in M and x in L }という多重集合を返します。
SPARQL集約の基礎となる集合関数は、すべて共通する符号を持っています。それは、SetFunc(M)、または、Mがリストの多重集合である場合はSetFunc(M, scalarvals)で、scalarvalsは、SPARQL文法の集約のために( ... ; key=value )構文によって集合関数に間接的に渡される1つ以上のスカラー値です。SPARQLクエリ1.1に組み込み済みの集約によってサポートされているこれを用いる唯一の方法は、GROUP_CONCAT
で、GROUP_CONCAT(?x ; separator=", ")
のように用います。
「集合関数」という名称が多少歴史的であることに注意してください ― 集合関数に対する引数は、実際に多重集合です。この名称は、SQL集合関数との共通性を持たせるために保持されており、多重集合でも機能します。
このドキュメントで定義している集合関数は、Count、Sum、Min、Max、Avg、GroupConcat、Sampleです ― COUNT
、SUM
、MIN
、MAX
、AVG
、GROUP_CONCAT
、SAMPLE
という集約に対応しています。定義は、以下の項にあります。システムは、ローカルの拡張でこの集合を拡張し、同じ記法を関数とキャストに用いることを選択できます。区切り文字である;を用いていない場合には、パーサは、集約が用いられているクエリにエラーがあるか否かかを判断できるようになる前に、あるIRIが関数、キャストまたは集約を参照しているか否かを知る必要があるということに注意してください。
Countは、与えられた式がバインドを持つ数と、集約グループ内の非エラー値を数えるSPARQL集合関数です。
定義: Count
xsd:integer Count(multiset M)N = Flatten(M)
remove error elements from N
Count(M) = card[N]
Sumは、集約グループ内の値を合計して得られる値を返すSPARQL集合関数です。op:numeric-add関数により型昇格が生じ、推移的に適用され(下記の定義を参照)、したがって、?xが1 (integer)、2.0e0 (float)、および3.0 (decimal)という値を持っている集約グループ内のSUM(?x)の値は、6.0 (float)になるでしょう。
定義: Sum
numeric Sum(multiset M)Sum集合関数は、構文内のSUM
集約に使われます。
Sum(M) = Sum(ToList(Flatten(M))).
Sum(S) = op:numeric-add(S1, Sum(S2..n)) when card[S] > 1
Sum(S) = op:numeric-add(S1, 0) when card[S] = 1
Sum(S) = "0"^^xsd:integer when card[S] = 0
In this way, Sum({1, 2, 3}) = op:numeric-add(1, op:numeric-add(2, op:numeric-add(3, 0))).
Avg集合関数は、グループの平均値を計算します。それは、SumとCountの用語で定義されます。
定義: Avg
numeric Avg(multiset M)Avg(M) = "0"^^xsd:integer, where Count(M) = 0
Avg(M) = Sum(M) / Count(M), where Count(M) > 0
例えば、Avg({1, 2, 3}) = Sum({1, 2, 3})/Count({1, 2, 3}) = 6/3 = 2です。
Minは、個々のグループの最小値を返すSPARQL集合関数です。
これは、SPARQL ORDER BYの順序付け定義を利用し、それによって、任意に型付きの式に順序付けが可能になります。
定義: Min
term Min(multiset M)Min(M) = Min(ToList(Flatten(M)))
Min({}) = error.
引数として渡された値の平坦化された多重集合は、シーケンスSに変換され、このシーケンスは、ORDER BY ASC
句に基づいて順序付けられます。
Min(S) = S0
Maxは、個々のグループの最大値を返すSPARQL集合関数です。
これは、SPARQL ORDER BYの順序付け定義を利用し、それによって、任意に型付きの式に順序付けが可能になります。
定義: Max
term Max(multiset M)Max(M) = Max(ToList(Flatten(M)))
Max({}) = error.
引数として渡された値の多重集合は、シーケンスSに変換され、このシーケンスは、ORDER BY DESC
句に基づいて順序付けられます。
Max(S) = S0
GroupConcatは、グループの式の値にまたがって文字列の連結を行なう集合関数です。文字列の順序は定められていません。連結で用いられる区切り文字は、スカラー引数のSEPARATORが用いられるかもしれません。
定義: GroupConcat
literal GroupConcat(multiset M)「区切り文字」のスカラー引数がGROUP_CONCATに存在していない場合は、UnicodeのコードポイントU+0020である「空白」文字とみなされます。
値の多重集合である、引数として渡されるMはシーケンスSに変換されます。
GroupConcat(M, scalarvals) = GroupConcat(Flatten(M), scalarvals("separator"))
GroupConcat(S, sep) = "", where |S| = 0
GroupConcat(S, sep) = CONCAT("", S0), where |S| = 1
GroupConcat(S, sep) = CONCAT(S0, sep, GroupConcat(S1..n-1, sep)), where |S| > 1
例えば、GroupConcat({"a", "b", "c"}, {"separator" → "."}) = "a.b.c"です。
我々は、eval(D(G), algebra expression)を、アクティブ・グラフGを持つデータセットDに関する代数式の評価であると定義しています。アクティブ・グラフは、最初はデフォルト・グラフです。
D : データセット D(G) : アクティブ・グラフGを持つデータセットD(パターンがマッチするもの) D[i] : データセットDにIRI iを持つグラフ P, P1, P2 : グラフ・パターン L : ソリューション・シーケンス F : 式
eval(D(G), Path(X, path, Y)) = multiset of solution mappings
プロパティー・パス式の項を参照してください。
eval(D(G), Filter(F, P)) = Filter(F, eval(D(G),P), D(G))
「substitute」は、exists
に置換されたEXISTS
とNOT EXISTS
の形式の評価をサポートするフィルタ関数です。
定義: Substitute
μをソリューション・マッピングとします。
substitute(pattern, μ) = the pattern formed by replacing every occurrence of a variable v in pattern by μ(v) for each v in dom(μ)
定義: Existsの評価
μをフィルタとグラフ・パターンPに対する現在のソリューション・マッピングとします。
The value exists(P), given D(G) is true if and only if eval(D(G), substitute(P, μ)) is a non-empty sequence.
eval(D(G), Join(P1, P2)) = Join(eval(D(G), P1), eval(D(G), P2))
eval(D(G), LeftJoin(P1, P2, F)) = LeftJoin(eval(D(G), P1), eval(D(G), P2), F)
eval(D(G), Union(P1,P2)) = Union(eval(D(G), P1), eval(D(G), P2))
if IRI is a graph name in D eval(D(G), Graph(IRI,P)) = eval(D(D[IRI]), P)
if IRI is not a graph name in D eval(D(G), Graph(IRI,P)) = the empty multiset
eval(D(G), Graph(var,P)) = Let R be the empty multiset foreach IRI i in D R := Union(R, Join( eval(D(D[i]), P) , Ω(?var->i) ) the result is R
グラフの評価は、SPARQL代数和集合演算子を使用します。ソリューション・マッピングのカーディナリティーは、それぞれのjoinの操作における、そのソリューション・マッピングのカーディナリティーの合計です。
eval(D(G), Group(exprlist, P)) = Group(exprlist, eval(D(G), P))
eval(D(G), Aggregation(exprlist, func, scalarvals, P)) = Aggregation(exprlist, func, scalarvals, eval(D(G), P))
eval(D(G), AggregateJoin(A1, ..., An)) = AggregateJoin(eval(D(G), A1), ..., eval(D(G), An))
eval(D(G), Ai)がエラーであれば、無視されることに注意してください。
eval(D(G), Extend(P, var, expr)) = Extend(eval(D(G), P), var, expr)
eval(D(G), ToList(P)) = ToList(eval(D(G), P))
eval(D(G), Distinct(L)) = Distinct(eval(D(G), L))
eval(D(G), Reduced(L)) = Reduced(eval(D(G), L))
eval(D(G), Project(L, vars)) = Project(eval(D(G), L), vars)
eval(D(G), OrderBy(L, condition)) = OrderBy(eval(D(G), L), condition)
eval(D(G), ToMultiSet(L)) = ToMultiSet(eval(D), M))
eval(D(G), Slice(L, start, length)) = Slice(eval(D(G), L), start, length)
SPARQLの全体的な設計は、基本グラフ・パターンにマッチングした条件を書き直すことによって、シンプルな含意ではなく、より精緻な形式の含意を想定したクエリに使用できます。1つの一般的な形式でそのような条件を記述し、それをすべての形式の含意に適用して不必要または不適切な重複を最適に排除することは、未解決の研究課題であるため、このドキュメントは、そのようなソリューションが満たすべき必要条件を提示するのみです。これらは、それぞれの具体的な事例に対する完全な定義に拡張する必要があるでしょう。
基本グラフ・パターンは、RDFグラフがRDFトリプルに対して行うトリプルのパターンと同じ関係にあり、同じ用語の多くをそれらに適用できます。特に、トリプル(M(s), M(p), M(o))が2番目のパターンにある場合に限りトリプル(s, p, o)が最初のパターンに存在するような、空白ノードを空白ノードにマッピングし、変数、リテラル、およびIRIをそれら自身にマッピングするトリプル・パターンの用語間に全単射Mがある場合、2つの基本グラフ・パターンはが同等であると述べられます。この定義は、変数名を同等なパターン全体で保持することによって、RDFグラフの同等性に対し、それを基本グラフ・パターンに拡張します。
含意レジーム(entailment regime)は、次の仕様を定めます。
様々な含意レジームのクエリに関する詳細な定義は、SPARQL 1.1含意レジームにあります。
いくつかの含意レジームは、いくつかのRDFグラフを、矛盾すると分類することができます。例えば、次のRDFグラフは、
_:x rdf:type xsd:string . _:x rdf:type xsd:decimal .
DがXSDデータ型を含んでいる場合、D矛盾です。矛盾したグラフへのクエリの効果は、この仕様ではカバーしていませんが、特定のSPARQLの拡張で指定しなければなりません。
結果として生じるソリューションの多重集合が、RDFグラフ同等の違は無視して、一意に決定されるような、条件を満たす任意の基本グラフ・パターンBGP、任意のRDFグラフG、および任意の評価に対し、含意レジームEは、基本グラフ・パターン評価の条件を提供しなければなりません。EをEval-E(G, BGP)とともに用いたGに対するBGPの評価に基づくソリューションの多重集合を示します。
含意レジームは、さらに次の条件を満たさなければなりません。
SG E-entails (SG union μ1(BGP1) union ... union μn(BGPn))
RDFがいくらでも重複を許すため、これらの条件は、ありえる答えの集合を完全に決定するわけではありません。さらに、したがって、下記が当てはまらなければなりません。
(a) SGは、しばしばAGと同等のグラフになるでしょうが、これをE-同等(E-equivalence)に制限すると、例えばセマンティックな重複の排除などのいくつかの形式の正規化をクエリの実行前にソース・ドキュメントに適用することが可能になります。
(b) 条件3の構築は、空白ノードがSGで出現する方法と内部的に整合性があるような方法で、ソリューション・マッピングによって導入された任意の空白ノードが確実に用いられるようになります。これにより、答えの集合の中の1つ以上の答えで、そのように識別された空白ノードが本当にSGにおいて同じであるときにのみ、空白ノード識別子が確実に生じます。拡張が空白ノードへのバインディングを許さない場合、この条件は以下の条件に簡略化できます。
SG E-entails μ(BGP) for each solution mapping μ.
(c) これらの条件は、SGがAGまたはBGPと空白ノードを共有しないという要件をSPARQLに課しません。特に、これによって、SGが実際にAGになることが可能になります。これにより、空白ノード識別子がクエリとソース・ドキュメントの間や複数のクエリにまたがって意味を保有するクエリ・プロトコルが可能になります。しかし、そのようなプロトコルは、現在のSPARQLプロトコル仕様ではサポートされていません。
(d) 条件1~3のみが答えにおける必要条件であるため、条件4では、正当な答えの集合を様々な方法で制限しうるケースが許されます。
(e) これらの条件は、BGPの空白ノードにおけるインスタンス・マッピングを明示的に参照しません。いくつかの含意レジームに関しては、1つのインスタンス・マッピングの存在によって、空白ノードの存在を表す解釈を完全に得ることができるわけではありません。これらの条件は、このようなレジームがクエリ・パターンの空白ノードに「完全に存在する」読込みを与えることを許します。
SGにおけるSPARQL条件が、AGにグラフ同等(graph-equivalent)であるけれども、AGやBGPと空白ノードを共有しないという(最初の条件を満たす)ものである場合、Eがシンプルな含意であるケースのこれらの条件をSPARQLが満たすということを示すと分かりやすいです。唯一の重要な条件は(3)です。
すべてのソリューション・マッピングμiに対し、基本グラフ・パターンマッチングの定義により、Piがμiとσiからなるパターン・インスタンス・マッピングである場合に、Pi(BGPi)がSGのサブグラフであるようなRDFインスタンス・マッピングσiがあります。BGPiとSGが共通の空白ノードを持たないため、σiとμiの範囲にはBGPiの空白ノードは含まれません。したがって、ソリューション・マッピングμiとPiのRDFインスタンス・マッピングσiは交換され、したがって、Pi(BGPi) = σi(μi(BGPi))です。したがって、次のとおりです。
P1(BGP1) union ... union Pn(BGPn)
= σ1(μ1(BGP1)) union ... union
σn(μn(BGPn))
= [ σ1 + ... + σn](
μ1(BGP1) union ... union
μn(BGPn) )
これは、σi RDFインスタンス・マッピングの定義域がすべて互いに排他的であるためです。これらがSGから排他的であるためでもあります。
SG union [ σ1 + ... + σn](
μ1(BGP1) union ... union μn(BGPn) )
= [ σ1 + ... + σn](SG union
μ1(BGP1) union ... union μn(BGPn) )
すなわち、
SG union μ1(BGP1) union ... union μn(BGPn)
は、SGのサブグラフであるインスタンスを持っており、そのため、RDF補間定理[RDF-MT]によるSGによって簡単に含意されます。
SPARQL文法はSPARQLクエリとSPARQL更新の両方をカバーします。
SPARQLリクエスト文字列は、SPARQLクエリ文字列あるいはSPARQL更新文字列で、次の文法によって定義された言語のUnicode文字列(6.1項[CHARMOD]文字列の概念を参照)です。
QueryUnit生成規則でのSPARQLクエリ文字列の開始
UpdateUnit生成規則でのSPARQL更新文字列の開始
Unicodeの将来のバージョンとの互換性のため、この文字列中の文字には、この文書の発表時点には割り当てられていないUnicodeコード・ポイントが含まれているかもしれません(識別子とパターン構文[UNIID]の4項 パターン構文を参照)。除外されている文字クラス(例えば、[^<>'{}|^`]
)を持つ生成規則の場合、文字は#x0 - #x10FFFF
の範囲から除外されています。
SPARQLクエリ文字列は、以下のEBNFで定義された文法によって分析する前に、コードポイント・エスケープ・シーケンス用に処理されます。SPARQLクエリ文字列用のコードポイント・エスケープ・シーケンスは、以下の通りです。
エスケープ | Unicodeコードポイント |
---|---|
'\u' HEX HEX HEX HEX | コード化された16進の値に対応する包括的な範囲U+0~U+FFFFのUnicodeコード・ポイント。 |
'\U' HEX HEX HEX HEX HEX HEX HEX HEX | コード化された16進の値に対応する包括的な範囲U+0~U+10FFFFのUnicodeコード・ポイント。 |
ここでは、HEXは16進の文字です。
HEX ::= [0-9] | [A-F] | [a-f]
例:
<ab\u00E9xy> # Codepoint 00E9 is Latin small e with acute - e \u03B1:a # Codepoint x03B1 is Greek small alpha - α a\u003Ab # a:b -- codepoint x3A is colon
コードポイント・エスケープ・シーケンスは、クエリ文字列のどこにでも出現できます。これらは、文法規則に基づいた分析の前に処理され、したがって、接頭辞付き名前をマーク付けする「:
」のような、文法中で重要性を持つコードポイントに置き換えられることがあります。
これらのエスケープ・シーケンスは、以下の文法に含まれていません。その時点で文法上正当な文字列のエスケープ・シーケンスのみが示されるかもしれません。例えば、変数「?x\u0020y
」は、正当ではありません(\u0020
はスペースであり、変数名では許されていない)。
空白(生成規則WS
)は2つの終端記号を区切るために用いられ、そうでなければ、1つの終端記号として(誤)認識されます。下記の大文字の規則名は、空白が重要である場合を示します。これらは、SPARQLパーサを構築するための可能な端末の選択を形成します。文字列において空白は重要です。そうでない場合には、トークンの間では空白は無視されます。
例えば、
?a<?b&&?c>?d
は、トークン・シーケンスの変数「?a
」、IRI「<?b&&?c>
」、変数「?d
」であり、「<
」(小なり)および「>
」(大なり)を用いた2つの式を結合した演算子「&&
」を含んだ式ではありません。
SPARQLクエリにおけるコメントは、IRI中または文字列中以外では、「#
」の形式を取り、これは、行末(文字列0x0D
または0x0A
でマーク付けされる)まで続くか、コメント・マーカーの後に行末がなければファイルの終りまで続きます。コメントは空白として扱われます。
IRIREF
生成規則およびPrefixedName
(接頭辞拡張の後の)生成規則でマッチングされたテキストは、エスケープ処理の後に、RFC 3987 [RFC3987]の2.2項「IRI参照およびIRIのためのABNF」のIRI参照の一般的な構文に適合していなければなりません。例えば、IRIREF
<abc#def>
は、SPARQLクエリ文字列で出現可能ですが、IRIREF
<abc##def>
は出現できません。
キーワードBASEで宣言された基底IRIは、絶対IRIでなければなりません。キーワードPREFIXで宣言された接頭辞は、同じクエリ中で再宣言できません。BASEとPREFIXの記述に関しては、4.1.1項、IRI用語の構文を参照してください。
空白ノードは、次の中では使用できません。
空白ノード・ラベルのスコープは、それが発生するSPARQLリクエスト文字列です。リクエスト文字列中の同じ空白ノード・ラベルを様々に用いても、同じブランクのノードを指します。リクエストごとに新しい空白ノードが生成されます。空白ノードは、リクエストにまたがるラベルによって参照することはできません。
同じ空白ノード・ラベルは、次の中では使用できません。
WHERE
句INSERT DATA
操作SPARQL更新リクエスト内の異なるQuadPattern句に同じ空白ノード・ラベルが生じる可能性があることに注意してください。
コードポイント・エスケープ・シーケンスに加え、下記は、任意のstring
生成規則(例えば、STRING_LITERAL1
、STRING_LITERAL2
、STRING_LITERAL_LONG1
、STRING_LITERAL_LONG2
)のエスケープ・シーケンスを行います。
エスケープ | Unicodeコードポイント |
---|---|
'\t' | U+0009(タブ) |
'\n' | U+000A(改行) |
'\r' | U+000D(復帰) |
'\b' | U+0008(バックスペース) |
'\f' | U+000C(改ページ) |
'\"' | U+0022(引用符、二重引用符) |
"\'" | U+0027(アポストロフィ、一重引用符) |
'\\' | U+005C(逆斜線) |
例:
"abc\n" "xy\rz" 'xy\tz'
文法で用いられるEBNF表記法は、XML(Extensible Markup Language)1.1[XML11]の6項の表記法で定義されています。
注意:
rdf:type
の代わりに用いられるキーワード「a
」を除き、大文字・小文字を区別しない方法でマッチします(完全形では、http://www.w3.org/1999/02/22-rdf-syntax-ns#type
)。QueryUnit
と、SPARQL更新リクエスト用のUpdateUnitの2つあります。AdditiveExpression
文法規則は、符号付きの数字が後続する式の2つのケースをカバーすることで、これを可能にします。これらにより、必要に応じて、符号のない数の加算または減算が生じます。INSERT DATA
、DELETE DATA
、DELETE WHERE
というトークンでは、空白はその単語間にいくつでも認められています。シングル・スペースのバージョンは、明瞭さのために文法で用いられます。QuadData
とQuadPattern
の両方の規則は、Quads
の規則を用います。INSERT DATA
およびDELETE DATA
で用いられるQuadData
という規則は、クアッド・パターンにおいて変数を認めてはなりません。DELETE WHERE
(DELETE
用のDeleteClause
)でも、DELETE DATA
でも認められていません。VALUES
ブロックの変数リスト内の変数の数は、DataBlock
の関連する値の各リストの数と同じでなければなりません。SELECT
句でAS
によって導入された変数は、既に範囲内にあってはなりません。BIND
句で割り当てられている変数は、GroupGraphPattern
内の直前のTriplesBlock
内で既に使用されていてはなりません。終端記号の生成規則:
[139] |
IRIREF |
::= | '<' ([^<>"{}|^`\]-[#x00-#x20])* '>' |
[140] |
PNAME_NS |
::= | PN_PREFIX? ':' |
[141] |
PNAME_LN |
::= | PNAME_NS PN_LOCAL |
[142] |
BLANK_NODE_LABEL |
::= | '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)? |
[143] |
VAR1 |
::= | '?' VARNAME |
[144] |
VAR2 |
::= | '$' VARNAME |
[145] |
LANGTAG |
::= | '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* |
[146] |
INTEGER |
::= | [0-9]+ |
[147] |
DECIMAL |
::= | [0-9]* '.' [0-9]+ |
[148] |
DOUBLE |
::= | [0-9]+ '.' [0-9]* EXPONENT | '.' ([0-9])+ EXPONENT | ([0-9])+ EXPONENT |
[149] |
INTEGER_POSITIVE |
::= | '+' INTEGER |
[150] |
DECIMAL_POSITIVE |
::= | '+' DECIMAL |
[151] |
DOUBLE_POSITIVE |
::= | '+' DOUBLE |
[152] |
INTEGER_NEGATIVE |
::= | '-' INTEGER |
[153] |
DECIMAL_NEGATIVE |
::= | '-' DECIMAL |
[154] |
DOUBLE_NEGATIVE |
::= | '-' DOUBLE |
[155] |
EXPONENT |
::= | [eE] [+-]? [0-9]+ |
[156] |
STRING_LITERAL1 |
::= | "'" ( ([^#x27#x5C#xA#xD]) | ECHAR )* "'" |
[157] |
STRING_LITERAL2 |
::= | '"' ( ([^#x22#x5C#xA#xD]) | ECHAR )* '"' |
[158] |
STRING_LITERAL_LONG1 |
::= | "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR ) )* "'''" |
[159] |
STRING_LITERAL_LONG2 |
::= | '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR ) )* '"""' |
[160] |
ECHAR |
::= | '\' [tbnrf\"'] |
[161] |
NIL |
::= | '(' WS* ')' |
[162] |
WS |
::= | #x20 | #x9 | #xD | #xA |
[163] | ANON |
::= | '[' WS* ']' |
[164] |
PN_CHARS_BASE |
::= | [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] |
[165] |
PN_CHARS_U |
::= | PN_CHARS_BASE | '_' |
[166] |
VARNAME |
::= | ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )* |
[167] |
PN_CHARS |
::= | PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] |
[168] |
PN_PREFIX |
::= | PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)? |
[169] |
PN_LOCAL |
::= | (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )? |
[170] |
PLX |
::= | PERCENT | PN_LOCAL_ESC |
[171] |
PERCENT |
::= | '%' HEX HEX |
[172] |
HEX |
::= | [0-9] | [A-F] | [a-f] |
[173] |
PN_LOCAL_ESC |
::= | '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' ) |
SPARQLクエリ文字列の適合性に関しては19 SPARQL文法の項を、クエリ結果の適合性に関しては16 クエリ形式の項を参照してください。application/sparql-queryメディア・タイプへの適合性に関しては22. インターネット・メディア・タイプを参照してください。
この仕様は、SPARQL 1.1プロトコル[SPROT]、SPARQLクエリ結果XMLフォーマット[SPARQL XML Results]、SPARQL 1.1クエリ結果JSONフォーマット[SPARQL-JSON-Results]、SPARQL 1.1クエリ結果CSVおよびTSVフォーマット[SPARQL CSV and TSV Results]との併用を意図しています。これらの適合性基準に関してはそれらの仕様を参照してください。
SPARQLプロトコルが、SPARQLクエリをSPARQLクエリ処理サービスに伝え、要求を行ったエンティティーにクエリ結果を返すための手段を記述しているということに注意してください。
FROM、FROM NAMED、またはGRAPHを用いたSPARQLクエリは、指定されたURIを逆参照するかもしれません。これは、サービスの拒否などの関連する副次的な問題と共に、ネットワーク、ディスクまたはCPU資源の追加使用を招くかもしれません。URI(Uniform Resource Identifier):一般的構文[RFC3986]の7項のセキュリティ問題について考察する必要があります。さらに、場合によっては、file:
URIのコンテンツにアクセスし、処理し、結果として返すことができ、ローカル資源への予期しないアクセスが行われます
FROM NAMEDなど、SPARQLリクエストによって、SPARQLエンドポイントからのリクエストが追加で発行されるかもしれません。エンドポイントは潜在的に、組織のファイアウォールやDMZ内にあり、したがって、このようなクエリは、間接的な攻撃の原因となるかもしれません。
SPARQL言語は拡張を認めており、それには独自のセキュリティ上の影響があるでしょう。
複数のIRIが同じ外観を持っているかもしれません。異なるスクリプトの文字が同じに見えるかもしれません(キリル文字の「о」はラテン文字の「o」と同じに見えるかもしれません)。 結合文字が後続する文字は、別の文字と同じ視覚的表現を持っているかもしれません(結合アキュート・アクセントが後続するラテン小文字Eは、アキュート付きラテン小文字Eと同じ視覚的表現を持っています)。SPARQLのユーザは、注意してデータ中のIRIにマッチするIRIを持つクエリを構築しなければなりません。類似している文字のマッチングに関する詳細は、Unicodeセキュリティに関する留意点[UNISEC]およびIRI(Internationalized Resource Identifiers)[RFC3987]の8項にあります。
SPARQLクエリ言語のインターネット・メディア・タイプ/MIMEタイプは、「application/sparql-query」です。
sparqlクエリ・ファイルは、すべてのプラットホーム上で拡張子「.rq」(小文字)であることが推奨されます。
マッキントッシュHFSファイル・システム上に保存されたsparqlクエリ・ファイルには、ファイル・タイプ「TEXT」が付与されていることが推奨されます。