Negazione SPARQL: tutti gli ingredienti: agenti che non sono prodotti: persone
Domanda
Sto provando a scrivere una query SPARQL che dovrebbe darmi tutto foaf: Agenti
che non sono foaf: Persone
.
Non riesco a vedere un modo per applicare questo OPTIONAL / BOUND costruire a questo problema, perché tutte le proprietà come rdfs: subClassOf
e rdf: type
sono transitive e riflessive.
Ho provato questo:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person }
FILTER ( !BOUND(?y) ) }
Ma rdf: type sembra essere transitivo, almeno con JENA / ARQ / SDB.
Soluzione
Il motivo per cui non funziona è perché hai due associazioni variabili separate (? x
e ? y
) non correlate alla tua query. Quindi ? X
deve essere associato per apparire nel set di risultati (che è quello che vuoi), ma se ? Y
non è associato, non hai imparato nulla di nuovo su ? x
.
Aggiornamento: in una query ideale, non sarebbe necessario ? y
; potresti testare direttamente gli edeg entranti / uscenti di ? x
. Questo è difficile (impossibile?) Da fare in SPARQL 1.0 quando si desidera verificare se non esiste un bordo su un dato bind variabile. Tuttavia, SPARQL 1.1 fornirà supporto per la negazione:
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 . }
}
L'approccio di @Kingsley Idehen (usando estensioni SPARQL di terze parti) dovrebbe aiutarti a risolvere il problema a breve termine.
Altri suggerimenti
Per farlo in SPARQL 1.0, dovresti scrivere:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person . FILTER (?x = ?y) . }
FILTER ( !BOUND(?y) )
}
Come dice Phil M , SPARQL 1.1 introdurrà una nuova sintassi per rendere la scrittura molto più semplice.
Ecco la (bozza) specifica SPARQL 1.1 per la negazione: http: // www. w3.org/TR/sparql11-query/#negation
Tramite le estensioni Virtuoso SPARQL endpoint per la verifica http://lod.openlinksw.com/sparql (LOD Cloud Cache Instance)
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
Ora funziona come segue, per gentile concessione di 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 . })
}
Link di esempio live: