Bla*_*lia 3 sparql blank-nodes
请看下面的图表:
:Foo :p _:b0 ;
:p _:b1 ;
:p _:b2 .
_:b0 :p1 :apple ;
:p2 :banana .
_:b1 :p3 :cantaloupe ;
:p4 :date ;
:p5 :elderberry .
_:b2 :p6 :fig .
Run Code Online (Sandbox Code Playgroud)
注意: :Foo是具有相同谓词的三个三元组的主语:p.每个三元组都有一个空白节点作为其对象.
是否可以编写一个SPARQL查询来选择仅_:b1作为主题的所有三元组?
编辑:在提出答案之前,请理解我正在寻找一个聪明的解决方案来解决我在SPARQL中的问题.假设三重存储是固定的(即:无法完成任何更改数据).我在上面展示的图表是人为的; 每个空白节点没有相同数量的p/o三元组.但是如果他们每个都有一个三元组,那么以下SPARQL查询可能就足够了:
select ?b1 where {
:Foo :p ?bn .
?bn ?p ?o
} limit 1 offset 1
Run Code Online (Sandbox Code Playgroud)
显然,这里的关注点是每次返回相同的空白节点.我知道这是一套固有的无序,因此无法保证可重复的结果排序; 但老实说......对于一个固定的三重商店,我真诚地怀疑DFA会在查询之间返回不同的空白节点顺序.任何聪明的想法?
您无法在SPARQL中选择"第n个"空白节点,原因有两个:
在RDF/SPARQL中,您以间接方式处理空白节点:而不是尝试直接解决它们(正如我们在上面看到的那样,因为空白节点的定义是没有标识符),所以你看看将它们连接到其他资源的东西,即它们所涉及的语句.毕竟,这些语句赋予空白节点其上下文含义.
在您的情况下:它们_:b1和其他两个空白节点之间的差异在它们扮演主题角色的语句中.因此,要在SPARQL中查询_:b1作为主题的三元组,您应该查看数据并查看,_:b1唯一具有:p3值的属性:cantaloupe.所以你可以像这样查询:
CONSTRUCT { ?s ?p ?o }
WHERE { :Foo :p ?s .
?s :p3 :cantaloupe ;
?p ?o .
}
Run Code Online (Sandbox Code Playgroud)
在旁注:几个SPARQL引擎实现提供了一些功能来解决没有(全局)标识符的空白节点的问题.在许多情况下,它们引入了一些非标准语法扩展或自定义函数,允许您直接寻址SPARQL查询中的空白节点.我想强调的是,这是非标准的,不太可能在不同的端点上工作,因此最好避免使用.
如果你发现如果没有直接寻址空白节点就无法工作,你应该考虑在你的数据中根本不使用空白节点,而是为这些东西创建适当的IRI.
更新你对这个问题的更新基本上是这样的:"我可以在一个未命名的SPARQL特定实现中使用一些未记录的功能来进行严格来说不合法的查询,或者不保证给出我想要的结果,侥幸逃脱吗?" 这个问题的答案是:可能是的,但这取决于你正在使用哪个SPARQL实现,而且这是一个非常糟糕的想法,因为我上面提到的所有原因.
在实践中,许多(大多数?)三重存储确实会在查询之间以相同的顺序返回相同的结果,但这并不能保证(我不能强调这一点)并且你真的不应该依赖它.当然,你可以通过使用得到一个有序的查询结果ORDER BY的查询条款,但由于空节点的相对顺序在SPARQL是不确定的(即不会在这种情况下,有助于使查询引擎是免费的返回_:b1和_:b2任何命令它认为合适,即使有一个ORDER BY条款).更糟糕的是:虽然您的输入RDF文件可能包含空白节点标识符_:b1和_:b2,这不一定是SPARQL查询将返回的内容.许多三元组用内部生成的id替换空白节点标识符,并且您的SPARQL查询很可能返回_:genid-908c909aeacc4b6da3d3059e18706d68-b1而不是简单_:b1.
即使你可以以某种方式可靠地获得空白节点ID:你要用它做什么?空白节点为空.它携带的id仅用于内部簿记目的 - 您不能使用空白节点进一步查询.
相信我:这是一个坏主意.如果无法更改数据,请依赖连接空白节点的属性并查询这些属性.