SPARQL Negação: Todos foaf: Agentes que não são foaf: Pessoas
Pergunta
Eu estou tentando escrever uma consulta SPARQL que deve me dar todo foaf:Agents
que não são foaf:Persons
.
Eu não posso ver uma maneira de aplicar este OPCIONAL / VINCULADO construir para este problema, porque todos os imóveis como rdfs:subClassOf
e rdf:type
são transitivos e reflexiva.
Eu tentei isso:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person }
FILTER ( !BOUND(?y) ) }
Mas rdf: type parece ser transitivo, pelo menos com JENA / ARQ / SDB
.Solução
A razão isso não está funcionando é porque você tem duas ligações variáveis ??separadas (?x
e ?y
) que não estão relacionados na sua consulta. Então ?x
deve ser obrigado a aparecer no conjunto de resultados (que é o que você quer), mas se ?y
é desvinculado, você não aprendeu nada de novo sobre ?x
.
Update: Em uma consulta ideal, não haveria necessidade de ?y
em tudo; você poderia testar os edegs de entrada / saída de ?x
diretamente. Isto é difícil (impossível?) A fazer em SPARQL 1.0 quando você quiser verificar se uma vantagem não existe em uma determinada ligação variável. No entanto, SPARQL 1.1 fornecerá suporte para a negação:
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 . }
}
A abordagem de @Kingsley Idehen (usando extensões SPARQL de terceiros) deve ajudá-lo a resolver o problema no curto prazo.
Outras dicas
Para fazer isso no SPARQL 1.0, você teria que escrever:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person . FILTER (?x = ?y) . }
FILTER ( !BOUND(?y) )
}
Como Phil M diz , SPARQL 1.1 irá introduzir nova sintaxe para fazer este muito mais simples de escrever.
Aqui está o (draft) SPARQL 1.1 especificação para a negação: http: // www. w3.org/TR/sparql11-query/#negation
Via Virtuoso SPARQL Extensions endpoint para verificação http://lod.openlinksw.com/sparql (LOD Nuvem Cache Instância)
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
A seguir agora funciona, cortesia de 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 . })
}
exemplo vivo links: