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 . })
}

живой пример ссылки:

  1. Решение Запросов

  2. Определение Запрос