SPARQL отрицание: все foaf: агенты, которые не являются foaf:лица
Я пытаюсь написать запрос SPARQL, который должен дать мне все foaf:Agents
, не foaf:Persons
.
Я не вижу способа применить эта необязательная / связанная конструкция к этой проблеме, потому что все свойства, как rdfs:subClassOf
и rdf:type
является транзитивным и рефлексивным.
Я попытался это:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person }
FILTER ( !BOUND(?y) ) }
но rdf: type кажется транзитивным, по крайней мере, с JENA/ARQ/SDB.
5 ответов
почему это не работает, потому что у вас есть две отдельные переменные (?x
и ?y
), которые не связаны с вашим запросом. Так что ?x
должен обязательно появиться в результирующем наборе (что вы хотите), но если ?y
не связан, вы не узнали ничего нового о ?x
.
Update: в идеальном запросе не было бы необходимости в ?y
вообще; вы можете проверить входящие / исходящие edegs ?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) )
}
как говорит Фил м, 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 . })
}
живой пример ссылки: