SPARQL否定:すべてのfoaf:foafではないエージェント:Persons
質問
foaf:Persons
ではないすべての foaf:Agent
を提供するSPARQLクエリを作成しようとしています。
このOPTIONAL / BOUNDを適用する方法がわかりません rdfs:subClassOf
や rdf:type
などのすべてのプロパティは推移的かつ再帰的であるため、この問題を構成します。
これを試しました:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person }
FILTER ( !BOUND(?y) ) }
しかし、少なくともJENA / ARQ / SDBでは、rdf:typeは推移的であるようです。
解決
これが機能しない理由は、クエリ内で無関係な2つの別個の変数バインディング(?x
および?y
)があるためです。したがって、?x
を結果セットに表示するようにバインドする必要があります(これは必要です)が、?y
がバインドされていない場合は、?x
。
更新:理想的なクエリでは、?y
はまったく必要ありません。 ?x
の着信/発信エッジを直接テストできます。これは、SPARQL 1.0で、特定の変数バインディングにエッジが存在しないかどうかを確認する場合に実行するのは困難です(不可能ですか?)。ただし、 SPARQL 1.1 は否定のサポートを提供します。
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?agent
WHERE
{
?agent rdf:type foaf:Agent .
FILTER NOT EXISTS { ?agent rdf:type foaf:Person . }
}
@Kingsley Idehenのアプローチ(サードパーティのSPARQL拡張機能を使用)は、短期的には問題の解決に役立つはずです。
他のヒント
SPARQL 1.0でこれを行うには、次のように記述する必要があります。
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person . FILTER (?x = ?y) . }
FILTER ( !BOUND(?y) )
}
Phil Mが言うように、SPARQL 1.1はこれをより簡単にするための新しい構文を導入します。
否定のSPARQL 1.1仕様(ドラフト)は次のとおりです。 http:// www。 w3.org/TR/sparql11-query/#negation
Virtuoso SPARQL拡張機能を介して 検証用のエンドポイント http://lod.openlinksw.com/sparql (LODクラウドキャッシュインスタンス)
SELECT distinct ?x ?o
WHERE {
?x a foaf:Agent .
?x ?p ?o.
filter (!bif:exists ((select (1) where { ?x a foaf:Person } )))
}
limit 10
DESCRIBE ?x
WHERE {
?x a foaf:Agent .
filter (!bif:exists ((select (1) where { ?x a foaf:Person } )))
}
limit 200
SPARQL 1.1の好意により、以下が機能するようになりました。
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT COUNT(?agent)
WHERE
{
?agent rdf:type foaf:Agent .
FILTER (NOT EXISTS { ?agent rdf:type foaf:Person . })
}
ライブサンプルリンク: