SPARQL否定:所有不是foaf:Persons的foaf:Agents

12

我试图编写一个SPARQL查询,该查询应该给出所有不是 foaf:Personsfoaf:Agents

我无法想到如何将这个OPTIONAL/BOUND构造应用于这个问题,因为像 rdfs:subClassOfrdf:type 这样的属性是传递和自反的。

我尝试了这个:

SELECT * WHERE { 
?x rdf:type foaf:Agent 
OPTIONAL { ?y rdf:type foaf:Person } 
FILTER ( !BOUND(?y) ) }

但是 rdf:type 看起来是可传递的,至少在 JENA / ARQ / SDB 中是这样。

5个回答

13
这个不起作用的原因是你在查询中有两个不相关的变量绑定(?x?y),所以?x必须被绑定到结果集中(这正是你想要的),但如果?y未被绑定,你就没有学到任何关于?x的新知识。
更新:在理想的查询中,根本不需要?y;你可以直接测试?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扩展)应该可以帮助您在短期内解决这个问题。


但是我如何在?x和?y之间建立关系? - Juri Glass
SPARQL 1.1肯定会有否定,ISWC 2009的工作小组委员会对此非常明确。 - RobV
1
请注意,SPARQL 1.1语法(如链接中所指定的)现在实际上是FILTER NOT EXISTS(需要前置FILTER关键字)。 - Tom Saleeba

9
要在SPARQL 1.0中实现此操作,您需要编写以下代码:
SELECT * WHERE { 
     ?x rdf:type foaf:Agent 
     OPTIONAL { ?y rdf:type foaf:Person . FILTER (?x = ?y) . } 
     FILTER ( !BOUND(?y) ) 
}

正如Phil M所说,SPARQL 1.1将引入新的语法,使这个过程变得更加简单易懂。


2

通过 Virtuoso 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 

2

以下代码现在可以工作,感谢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. 查询定义


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接