SPARQLthon20/FederatedQueryTips

提供:TogoWiki

移動: 案内, 検索

目次

Virtuosoでの実行

デフォルトではService句は使えない。 インストール後に以下の設定を行う必要がある。

SQL> grant select on "DB.DBA.SPARQL_SINV_2" to "SPARQL";
SQL> grant execute on "DB.DBA.SPARQL_SINV_IMP" to "SPARQL";
SQL> GRANT EXECUTE ON DB.DBA.SPARUL_LOAD_SERVICE_DATA TO "SPARQL";
SQL> GRANT EXECUTE ON DB.DBA.SPARQL_SD_PROBE TO "SPARQL";
SQL> GRANT EXECUTE ON DB.DBA.L_O_LOOK TO "SPARQL";
SQL> grant execute on DB.DBA.RDF_QUAD to SPARQL_UPDATE;

Service句の変数について

Federate Queryができないと相談があったので調査

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX atlasterms: <http://rdf.ebi.ac.uk/terms/atlas/>
PREFIX core:<http://purl.uniprot.org/core/>

SELECT *
FROM <http://rdf.ebi.ac.uk/dataset/atlas/13.07>
WHERE {
  ?probe atlasterms:dbXref ?up_id
   SERVICE <http://togostanza.org/sparql> {
     ?up_id rdf:type core:Protein .
   }
} limit 10

一件よさそうなクエリに見えるが、ARQでは500番でエラーが吐かれ、Virtuosoでは以下のような不明なエラーログがでる。

Virtuoso RDFZZ Error DB.DBA.SPARQL_REXEC('http://togostanza.org/sparql', ...) has received result with unexpected variable name 'stubvar4'


原因:Service区内の変数が無い状態で問い合わせている。

WHERE句の最初の一行目で絞り込んで、?up_idの変数の値でService句を実行する。
このため、実際にFederateされる側のエンドポイント http://togostanza.org/sparql には次のようなクエリが投げられる。

 SELECT ?stubvar4 //この変数はVirtuosoが勝手にふるらしい。
 WHERE { 
     GRAPH <http://rdf.ebi.ac.uk/dataset/atlas/13.07> //FROM句に書いたグラフ名はここにも引き継がれている
  { <http://purl.uniprot.org/uniprot/A0JPT9> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.uniprot.org/core/Protein> .  }
  //?up_idのところに値(<http://purl.uniprot.org/uniprot/A0JPT9>)が埋められてクエリが実行されるので、SELECTで返す値がないクエリーになっている => エラー
 }

結合してもどうしようもない気はするが、少なくとも次のような書き方でSERVICE句に無理矢理変数を足すとエラーは消える。

SELECT *
FROM <http://rdf.ebi.ac.uk/dataset/atlas/13.07>
WHERE {
  ?probe atlasterms:dbXref ?up_id
   SERVICE <http://togostanza.org/sparql> {
     ?up_id rdf:type ?type FILTER(?type = core:Protein) .
   }
} limit 10

FROM句とSERVICEのグラフ

上記のクエリの場合Federate元のクエリのFROMで指定したGRAPH名はSERVICE内のクエリにも引き継がれる様子。
Federate元と先とでGRAPH名が同じ構成というケースはあまりない気がするので、FROM句よりはGRAPHで書いた方がお勧め。

SELECT *
WHERE {
  GRAPH <http://rdf.ebi.ac.uk/dataset/atlas/13.07> 
  {
    ?probe atlasterms:dbXref ?up_id
  }
  SERVICE <http://togostanza.org/sparql> {
    ?up_id rdf:type ?type FILTER(?type = core:Protein) .
  }
} limit 10

FederatedQueryの負荷

Federateクエリーはとても簡単にかけるものの、裏で行われている処理はかなり重たくなる場合がある。
たとえば先のクエリ例では、最初の条件
?probe atlasterms:dbXref ?up_id
で?up_idが出力されるが、これが80万件ある。実際にエンドポイントに最大件数のLIMITがかけられるので、1万件の?up_idになる。 その1万件に対してSERVICE句が発行されるので、FederatedQuery先の http://togostanza.org/sparql には負荷がかかることになる。