SPARQL查询以获取仅具有部分而非全部属性的实例

SPARQL查询以获取仅具有部分而非全部属性的实例,sparql,rdf,linked-data,Sparql,Rdf,Linked Data,假设我有三倍的形式 uri:ObjA1 uri:propAA uri:Obj1A . uri:ObjA1 uri:propAA uri:Obj1B . uri:ObjA2 uri:propAA uri:Obj1A . uri:ObjA2 uri:propAA uri:Obj1B . uri:ObjA2 uri:propAA uri:Obj1C . 现在,我要做的是找到所有实例,这些实例对于propAA只有值Obj1A和Obj1B。基本上,查询应该返回ObjA1而不是ObjA2,因为只有Obj

假设我有三倍的形式

uri:ObjA1 uri:propAA uri:Obj1A .
uri:ObjA1 uri:propAA uri:Obj1B .

uri:ObjA2 uri:propAA uri:Obj1A .
uri:ObjA2 uri:propAA uri:Obj1B .
uri:ObjA2 uri:propAA uri:Obj1C .
现在,我要做的是找到所有实例,这些实例对于propAA只有值Obj1A和Obj1B。基本上,查询应该返回ObjA1而不是ObjA2,因为只有ObjA1只为PROPA获取值Obj1A和Obj1B。我现在拥有的是

SELECT * where {
    ?sub uri:propAA uri:Obj1A .
    ?sub uri:propAA uri:Obj1B .
    FILTER NOT EXISTS {
        ?sub uri:propAA ?obj .
        FILTER((?obj != uri:Obj1A) && (?obj != uri:Obj1B)) .
    }
}

现在,这个查询起作用了。如果我没有放入filternotexists子句,那么它将同时返回ObjA1和ObjA2。我现在想知道是否有更好的方法来编写这个查询?更好的意思是,更高效或更简洁(或两者兼有)。

以三种模式表示,您正在为
?sub
寻找解决方案,其中
uri:propAA
的值都是
uri:Obj1A
uri:Obj1B
。这是SPARQL中的基本连词:

SELECT * 
WHERE {
   ?sub uri:propAA uri:Obj1A .
   ?sub uri:propAA uri:Obj1B .
}

您可以使用
NOT IN
操作符稍微缩短,也可以使用
连接器来避免重复三重模式:

SELECT * where {
    ?sub uri:propAA uri:Obj1A, uri:Obj1B .
    FILTER NOT EXISTS {
        ?sub uri:propAA ?obj .
        FILTER(?obj NOT IN (uri:Obj1A, uri:Obj1B))
    }
}
我怀疑这两种改变在性能方面都会有所不同,但它更简洁,而且(IMHO)更容易阅读


FWIW,这里的双重否定是重写普遍量化的经典方法。毕竟,逻辑上,
∀xp(x)
等于
∄x-P(x)
。由于SPARQL没有针对所有运算符的
,因此您必须处理
不存在
和双重否定。

我尝试了此查询,但它不起作用。它不会忽略除Obj1A和Obj1B外,propAA还有其他值的实例。我要寻找的是只获取那些将Obj1A和Obj1B作为PROPA值的实例。任何或多或少的东西都不应退还。在我给出的示例中,不应返回ObjA2,因为除了Obj1A和Obj1B作为PROPA的值外,它还将Obj1C作为PROPA的值。