SPARQL Отрицание: Все безразлично: Агенты, которые не безошибочно: Персоны
Вопрос
Я пытаюсь написать запрос 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.
Решение
Причина, по которой это не работает, заключается в том, что у вас есть две отдельные привязки переменных (? x
и ? y
), которые не связаны в вашем запросе. Таким образом, ? X
должен отображаться в наборе результатов (что вам нужно), но если ? Y
не связан, вы не узнали ничего нового о ? х код>.
Обновление: в идеальном запросе не было бы необходимости в ? 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 р>
Через виртуальные расширения SPARQL конечная точка для проверки http://lod.openlinksw.com/sparql (экземпляр LOD Cloud Cache)
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 . })
}
Примеры ссылок в реальном времени:
<Ол>