8.6 SPARQL問合せの実行モデル
Oracle RDF Graph Adapter for Eclipse RDF4J APIを介して実行されるSPARQL問合せは、RDFデータを格納するためのOracleのリレーショナル・スキーマに対するSQL問合せとして実行されます。
OracleのSQLエンジンを使用すると、SPARQL問合せの実行で、パラレル問合せ実行、インメモリー列表現、Exadataスマート・スキャンなどの多くのパフォーマンス機能を利用できます。
SPARQL問合せを実行するには、次の2つの方法があります。
-
Query
またはそのサブインタフェースのいずれかの実装を、基礎となるOracleSailConnection
を持つRepositoryConnection
のprepareQuery
関数から取得できます。 -
TupleExpr
のOracle固有の実装をOracleSPARQLParser
から取得し、OracleSailConnection
のevaluate
メソッドをコールできます。
次のコード・スニペットは、最初の方法を示しています。
//run a query against the repository String queryString = "PREFIX ex: <http://example.org/ontology/>\n" + "SELECT * WHERE {?x ex:name ?y} LIMIT 1 "; TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); try (TupleQueryResult result = tupleQuery.evaluate()) { while (result.hasNext()) { BindingSet bindingSet = result.next(); psOut.println("value of x: " + bindingSet.getValue("x")); psOut.println("value of y: " + bindingSet.getValue("y")); } }
OracleSailConnection
で問合せが評価されるときに、まずそのSPARQL問合せが同等のSQL問合せに変換されます。それが、その後、データベース・サーバーで実行されます。デフォルトでは、この問合せはクライアントでJavaコードを使用して変換されます。ただし、このSPARQLからSQLへの変換では、システム・プロパティoracle.rdf4j.adapter.sparqlInClient
が値F
に設定されている場合は、かわりにデータベース・サーバーでSEM_APIS.SPARQL_TO_SQL
ストアド・プロシージャを使用できます。SEM_APIS.SPARQL_TO_SQL
を使用すると、データベースのラウンドトリップが減少し、クライアントとデータベース・サーバーの間の待機時間が長い場合はパフォーマンスが向上する可能性があります。SQL問合せの結果は、標準のRDF4J問合せ結果インタフェースのいずれかを介して処理され、戻されます。
8.6.1 BIND値の使用
Oracle RDF Graph Adapter for Eclipse RDF4Jでは、Queryインタフェースで定義されたsetBinding
プロシージャなど、標準のRDF4Jバインド値APIを介してバインド値がサポートされます。Oracleでは、元のSPARQL問合せ文字列にSPARQL BIND
句を追加することでバインド値を実装します。
SELECT * WHERE { ?s <urn:fname> ?fname }前述の問合せでは、問合せ変数
?s
に値<urn:john>
を設定できます。この場合、変換後の問合せは次のようになります。 SELECT * WHERE { BIND (<urn:john> AS ?s) ?s <urn:fname> ?fname }
ノート:
このアプローチは、SPARQLの標準の変数スコープ・ルールに従います。したがって、最も外側のグラフ・パターンで認識されない問合せ変数(副問合せから投影されない変数など)は、バインド値に置換できません。親トピック: SPARQL問合せの実行モデル
8.6.2 JDBC BIND値の使用
Oracle RDF Graph Adapter for Eclipse RDF4Jを使用すると、SPARQL問合せに対して実行される基礎となるSQL文でJDBCバインド値を使用できます。JDBCバインド値の実装は、前の項で説明した標準のRDF4Jバインド値のサポートよりもはるかに高性能です。
JDBCバインド値のサポートでは、標準のRDF4J setBinding
APIが使用されますが、バインド変数は特定の方法で宣言する必要があり、特別な問合せオプションをORACLE_SEM_SM_NS
ネームスペース接頭辞とともに渡す必要があります。問合せに対してJDBCバインド変数を有効にするには、ORACLE_SEM_SM_NS
ネームスペース接頭辞(PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#USE_BIND_VAR=JDBC>
など)にUSE_BIND_VAR=JDBC
を含める必要があります。SPARQL問合せにこの問合せオプションが含まれる場合、単純なSPARQL BIND句に表示されるすべての問合せ変数が、対応するSQL問合せでJDBCバインド値として処理されます。単純なSPARQL BIND句が、BIND (<constant> as ?var)
の形式(BIND("dummy" AS ?bindVar1
など)を持つものです。
次のコード・スニペットは、JDBCバインド値の使用方法を示しています。
例8-4 JDBCバインド値の使用
// query that uses USE_BIND_VAR=JDBC option and declares ?name as a JDBC bind variable
String queryStr =
"PREFIX ex: <http://example.org/>\n"+
"PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n"+
"PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#USE_BIND_VAR=JDBC>\n"+
"SELECT ?friend\n" +
"WHERE {\n" +
" BIND(\"\" AS ?name)\n" +
" ?x foaf:name ?name\n" +
" ?x foaf:knows ?y\n" +
" ?y foaf:name ?friend\n" +
"}";
// prepare the TupleQuery with JDBC bind var option
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryStr);
// find friends for Jack
tupleQuery.setBinding("name", vf.createLiteral("Jack");
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
System.out.println(bindingSet.getValue("friend").stringValue());
}
}
// find friends for Jill
tupleQuery.setBinding("name", vf.createLiteral("Jill");
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
System.out.println(bindingSet.getValue("friend").stringValue());
}
}
ノート:
Oracle RDF Graph Adapter for Eclipse RDF4JのJDBCバインド値機能は、SEM_APIS.SPARQL_TO_SQLのバインド変数機能を使用します(SEM_APIS.SPARQL_TO_SQLによるバインド変数の使用を参照)。親トピック: SPARQL問合せの実行モデル
8.6.2.1 JDBCバインド値のサポートの制限
JDBCバインド値をサポートしているのは、SPARQL SELECTおよびASK問合せのみです。
JDBCバインド値のサポートには、次の制限があります。
- JDBCバインド値は次ではサポートされていません。
- SPARQL CONSTRUCT問合せ
- DESCRIBE問合せ
- SPARQL更新文
- 4000文字を超える長さのRDFロング・リテラル値は、JDBCバインド値として使用できません。
- 空白のノードは、JDBCバインド値として使用できません。
親トピック: JDBC BIND値の使用
8.6.3 他の機能をサポートするためのSPARQL問合せ構文への追加
Oracle RDF Graph Adapter for Eclipse RDF4Jでは、問合せを生成および実行するためのオプションを渡すことができます。問合せオプションを含むOracle固有の名前空間を使用してSPARQL名前空間接頭辞の構文をオーバーロードすることで、これらの機能を実装できます。名前空間の形式はPREFIX ORACLE_SEM_xx_NS
で、xx
は機能のタイプ(SM - SEM_MATCH
など)を示します。
8.6.3.1 問合せの実行オプション
PREFIX
を含めることで、問合せの実行オプションをデータベース・サーバーに渡すことができます。PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#option>
前述のSPARQL PREFIX
のoption
は、問合せの実行時に使用される問合せオプション(またはカンマで区切られた複数のオプション)を反映します。
次のオプションがサポートされています。
- DOP=n: 問合せに対する並列度(n)を指定します。
- ODS=n: 実行計画の生成時に使用するオプティマイザ動的サンプリングのレベルを指定します。
次の問合せ例では、ORACLE_SEM_FS_NS
接頭辞を使用して、問合せの実行に並列度4を使用することを指定しています。
PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#dop=4> PREFIX ex: <http://www.example.com/> SELECT * WHERE {?s ex:fname ?fname ; ex:lname ?lname ; ex:dob ?dob}
8.6.3.2 SPARQL_TO_SQL (SEM_MATCH)のオプション
次の形式のSPARQL PREFIX
を含めることで、SPARQL_TO_SQL
オプションをデータベース・サーバーに渡し、SPARQL問合せに対して生成されるSQLに影響を与えることができます。
PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#option>
前述のPREFIX
のoption
は、問合せの実行時に使用されるSPARQL_TO_SQL
オプション(またはカンマで区切られた複数のオプション)を反映します。
使用可能なオプションの詳細は、SEM_MATCH表関数を使用したRDFデータの問合せを参照してください。この接頭辞では、SEM_MATCH
またはSEM_APIS.SPARQL_TO_SQL
のオプション引数に有効としてリストされている任意の有効なキーワードまたはキーワード値ペアを使用できます。
次の問合せ例では、ORACLE_SEM_SM_NS
接頭辞を使用して、問合せ内のすべてのトリプル・パターンを結合するためにHASH結合を使用するように指定します。
PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#all_link_hash>
PREFIX ex: <http://www.example.org/>
SELECT *
WHERE {?s ex:fname ?fname ;
ex:lname ?lname ;
ex:dob ?dob}
8.6.4 SPARQL問合せのサポートで特に留意する点
この項では、SPARQL問合せのサポートで特に留意する点について説明します。
無制限のプロパティ・パス問合せ
デフォルトでは、Oracle RDF Graph Adapter for Eclipse RDF4Jは、無制限のSPARQLプロパティ・パス演算子+
および*
の評価を最大10回の繰返しに制限します。これは、all_max_pp_depth(n)
SPARQL_TO_SQL
オプションを使用して制御できます。n
は、+
または*
と一致する場合に許可される最大反復回数です。値をゼロに指定すると、最大反復回数は無制限になります。
all_max_pp_depth(0)
を使用します。 PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#all_max_pp_depth(0)> PREFIX ex: <http://www.example.org/> SELECT (COUNT(*) AS ?cnt) WHERE {ex:a ex:p1* ?y}
SPARQLデータセットの指定
Eclipse RDF4J用のアダプタでは、SPARQL問合せ文字列の外部でデータセットを指定できません。Operation
のsetDataset()
メソッドとそのサブインタフェースによるデータセットの指定はサポートされておらず、SailConnection
のevaluate
メソッドへのデータセット・オブジェクトの受渡しもサポートされていません。かわりに、SPARQL句FROM
およびFROM NAMED
を使用して、SPARQL問合せ文字列自体で問合せデータセットを指定します。
問合せタイムアウト
Operation
およびそのサブインタフェースでのsetMaxExecutionTime
メソッドによる問合せタイムアウトはサポートされていません。
ロングRDFリテラル
長さが4000バイトを超えるラージRDFリテラル値は、一部のSPARQL問合せ関数ではサポートされていません。詳細は、SEM_MATCH使用時の特別な考慮事項を参照してください。
親トピック: SPARQL問合せの実行モデル