假设我有三元组的形式
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仅为propAA获取值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)) .
}
}
现在,此查询有效。如果我没有放置FILTER NOT EXISTS子句,那么它返回ObjA1和ObjA2。我现在要找的是知道是否有更好的方法来编写这个查询?更好的意思是,更有效或更简洁(或两者兼而有之)。
答案 0 :(得分:0)
就三重模式而言,您正在寻找?sub
的解决方案,其中uri:propAA
的值均为uri:Obj1A
和uri:Obj1B
。这是SPARQL中的基本结合:
SELECT *
WHERE {
?sub uri:propAA uri:Obj1A .
?sub uri:propAA uri:Obj1B .
}
答案 1 :(得分:0)
您可以使用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))
}
}
我怀疑任何改变都会有所改变,性能方面,但它更简洁,而且(恕我直言)更容易阅读。
FWIW,这里的双重否定是重写通用量化的经典方法。毕竟,从逻辑上讲,∀x P(x)
等于∄x ¬P(x)
。由于SPARQL没有FORALL
运算符,因此您必须使用NOT EXISTS
和双重否定。