SPARQL代数:根据它们具有的三元组排除节点

时间:2015-03-15 19:32:07

标签: sparql semantic-web linked-data triples turtle-rdf

拍下这张图:

:thing1 a :Foo ;
    :has :A ;
    :has :B .

:thing2 a :Foo ;
    :has :B ;
    :has :A .

:thing3 a :Foo ;
    :has :A ;
    :has :B ;
    :has :C .

我想选择:thing1:thing2,但 :thing3

这是我编写的SPARQL查询。有更好的方法吗?

SELECT ?foo WHERE {
    ?foo a :Foo ;
        :has :A ;
        :has :B .
    MINUS {
        ?foo a :Foo ;
            :has :A ;
            :has :B ;
            :has ?anythingElse .
        FILTER(?anythingElse != :A && ?anythingElse != :B)
    }
}

2 个答案:

答案 0 :(得分:3)

MINUS的另一种选择是FILTER NOT EXISTS:

SELECT ?foo WHERE {
    ?foo a :Foo ;
        :has :A, :B .
   FILTER NOT EXISTS {
       ?foo :has ?other .
       FILTER (?other NOT IN (:A, :B))
    }
}

松散地说,找到所有?foo:A和:B,然后检查他们没有其他:有价值。

在执行效率方面,有一些优化可以将一些MINUS模式转换为FILTER NOT EXISTS,反之亦然,并且还有共享子模式的可能性。

如果没有优化器那么聪明,FILTER NOT EXISTS可能会更快,因为"?foo a:Foo; ;有:A,:B。"不重复,FILTER只考虑已通过"?foo a:Foo的项目; ;有:A,:B。"。

当所有效果(包括缓存)结合在一起时,只有一种方法可以知道哪些是真实数据。

答案 1 :(得分:0)

您可以使用NOT IN运算符而不是布尔表达式来执行此操作,如果将MINUS子句替换为{{1},则无需重复三个三元模式}子句:

FILTER NOT EXISTS

我怀疑性能会有显着差异,但查询更短更容易阅读。