【发布时间】:2014-07-14 21:20:33
【问题描述】:
我在使用 Allegrograph 4.13 时遇到了一个奇怪的行为
这是测试用例的数据
prefix : <http://example.com/example#>
INSERT DATA {
:A rdfs:label "A" .
:A :hasProp :Prop1 .
:Prop1 :Key "1" .
:Prop1 :Value "AA" .
:B :hasProp :Prop2 .
:Prop2 :Key "1" .
:Prop2 :Value "AA" .
:C :hasProp :Prop3 .
:C :hasProp :Prop4 .
:Prop3 :Key "1" .
:Prop3 :Value "AA" .
:Prop4 :Key "2" .
:Prop4 :Value "BB" .
}
鉴于:A,我需要找到具有完全相同属性的资源。 也就是说,我想找到 :B 而不是 :C,因为 :C 多了一个属性(键“2”和值“BB”)
另请参阅此问题Find individuals in SPARQL based on other relations / Compare sets
Joshua Taylor 提供的以下查询直接使用资源 (:A) 并完全符合我的要求:
prefix : <http://example.com/example#>
select ?other ?k ?v {
:A :hasProp [ :Key ?k ; :Value ?v ] .
?other :hasProp [ :Key ?k ; :Value ?v ] .
filter not exists {
{ :A :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
union
{
?other :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
}
}
答案:
-------------------
|other| k | v
|A | "1" | "AA"
|B | "1" | "AA"
-------------------
第二个是使用变量?a,因为我需要先根据一些条件找到:A(本例中为rdfs:label)
使用变量 ?a 查询:
prefix : <http://example.com/example#>
select ?other ?k ?v {
?a rdfs:label "A" .
?a :hasProp [ :Key ?k ; :Value ?v ] .
?other :hasProp [ :Key ?k ; :Value ?v ] .
filter not exists {
{ ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
union
{
?other :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
}
}
返回
-------------------
|other| k | v
|A | "1" | "AA"
|B | "1" | "AA"
|C | "1" | "AA"
-------------------
这个查询也返回 :C 在我看来这是错误的。
谁能解释这种行为或用其他三元存储/SPARQL 引擎验证这个测试用例吗?
附加测试
根据 cmets 中的要求,我为 rdfs 添加了前缀,并将空白节点替换为变量。这似乎没有效果。
prefix : <http://example.com/example#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?a ?pr1 ?pr2 ?other ?k ?v {
?a rdfs:label "A" .
# bind (:A as ?a) .
?a :hasProp ?pr1 .
?pr1 :Key ?k ; :Value ?v .
?other :hasProp ?pr2 .
?pr2 :Key ?k ; :Value ?v .
filter not exists {
{ ?a :hasProp ?pp1 .
?pp1 :Key ?kk ; :Value ?vv .
filter not exists { ?other :hasProp ?pp2 .
?pp2 :Key ?kk ; :Value ?vv .
}
}
union
{
?other :hasProp ?pp3 .
?pp3 :Key ?kk ; :Value ?vv .
filter not exists { ?a :hasProp ?pp4 .
?pp4 :Key ?kk ; :Value ?vv .
}
}
}
}
a pr1 pr2 other k v
A Prop1 Prop1 A "1" "AA"
A Prop1 Prop2 B "1" "AA"
A Prop1 Prop3 C "1" "AA"
如果我使用 BIND(已注释)而不是带有 rdfs:label 的行,它看起来是一样的。
【问题讨论】:
-
干得好!这更清晰,更独立!
-
您在此处的查询是否按原样运行?即,Allegro 是否自动插入 rdfs: 的定义?
-
如果用一些变量替换查询中的空白节点会发生什么?例如,如果您使用
?a rdfs:label "A". ?a :hasProp ?aprop . ?aprop :Key ?k ; ?Value ?v并且类似地使用?otherprop?我想知道这些匹配的资源是什么。 -
我将您回答的内容添加到问题中(答案已被删除,因为它不是答案,但它是有用的信息)。如果你还没有厌倦这个,你可以尝试另一个测试吗?如果您使用
filter not exists {…} filter not exists {…}而不是filter not exists { {…} union {…} }会怎样? -
我试过了,但没有任何改变。
标签: rdf sparql semantic-web allegrograph