我正在使用SPARQL将一个数据存储中的数据转换为另一种形式/本体/模式。
数据实际上是一个来源,但可以简化为一系列关系,例如:A produces D
+ B consumes D
。
:A0 :consumes :D0 ;
:produces :D1, :D2 .
:A1 :produces :D3 .
:A2 :consumes :D1, :D2 ;
:produces :D4 .
:A3 :consumes :D3, :D4 ;
:produces :D5, D6 .
(不能保证D总是由某个A产生,或被其他A消耗。但是每个D只能由一个A产生。)
我想获取数据依赖性的信息。查询示例如下:
CONSTRUCT {
?producer :hasNextStage ?consumer .
}
WHERE {
?producer :produces ?data .
OPTIONAL {
?consumer :consumes ?data .
FILTER (?producer != ?consumer)
}
}
一切都很好,直到这里。但是,我想了解更多信息,例如“通过数据将哪个A连接到另一个A”,
:A0 :hasInfluence :INFLUENCE .
:INFLUENCE :stage :A2 ;
:data :D1, :D2 .
如所示,这需要我构造一个新变量(:INFLUENCE
)并为其分配三元组。
有没有办法在SPARQL中做到这一点?
------更新后的问题------
根据cygri的回答,我将查询更改为:
CONSTRUCT {
?producer :hasInfluence ?influence .
?influence :stage ?consumer ;
:data ?data .
}
WHERE {
?producer :produces ?data .
OPTIONAL {
?consumer :consumes ?data .
FILTER (?producer != ?consumer)
BIND (IRI(CONCAT("http://my/ns/#", CONCAT(STRAFTER(STR(?producer), "#"), STRAFTER(STR(?consumer), "#")))) AS ?influence)
}
}
但是,BIND
子句似乎没有任何作用。缩短它后,问题出在?producer
变量上:如果我在此使用此变量,它将无法正常工作。似乎?producer
没有绑定在这里? (但是FILTER
确实有效。)
如果我将此BIND
子句移出OPTIONAL
,一切正常。但这不是直观的,我想知道为什么它无法在OPTIONAL
中使用?
答案 0 :(得分:1)
最简单的解决方案是完全避免在CONSTRUCT
模板中使用新变量,而只使用一个空白节点:
CONSTRUCT {
?producer :hasInfluence [
:stage ?consumer;
:data ?data
]
}
这将产生所需的图形结构。如果您坚持使用IRI代替影响节点的空白节点(您可能应该这样做),那么您将需要:
CONSTRUCT {
?producer :hasInfluence ?influence.
?influence :stage ?consumer;
:data ?data.
}
WHERE {
...
BIND (IRI(xxx) AS ?influence)
}
这将为变量?influence
分配一个新的IRI,并在CONSTRUCT
模板中使用该变量。
现在,xxx
只是用于计算IRI的表达式的占位符。您没有提供足够的细节来说明应该包含的内容。每个数据节点都会有一个影响节点吗?如果是这样,您可以采用数据IRI的字符串形式:str(?data)
,并使用replace(s, search, replace)
进行一些字符串替换,以为影响节点创建一个很好的唯一IRI。