SPARQL:选择第n个空白节点

SPARQL:选择第n个空白节点,sparql,blank-nodes,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 . 注意::Foo是三个三元组的主语,具有相同的谓词,:p。每个三元组都有一个blanknode作为其对象 是否可以编写一个SPARQL查询来选择所有三元组,其中只有\ub1是主

以下图为例:

:Foo :p _:b0 ;
   :p _:b1 ;
   :p _:b2 .

_:b0 :p1 :apple ;
   :p2 :banana .

_:b1 :p3 :cantaloupe ;
   :p4 :date ;
   :p5 :elderberry .

_:b2 :p6 :fig .
注意:
:Foo
是三个三元组的主语,具有相同的谓词,
:p
。每个三元组都有一个blanknode作为其对象


是否可以编写一个SPARQL查询来选择所有三元组,其中只有
\ub1
是主题


编辑:在提出答案之前,请理解我正在SPARQL中寻找一个聪明的问题解决方案。假设三重存储是固定的(即:无法更改数据)。我上面显示的图表是人为设计的;每个blanknode的p/o三元组数不相同。但是,如果它们每个都有一个三元组,那么下面的SPARQL查询可能就足够了:

select ?b1 where {
   :Foo :p ?bn .
   ?bn ?p ?o
} limit 1 offset 1

显然,这里的问题是每次都返回相同的blanknode。我知道它是一个集合,本质上是无序的,因此不能保证结果排序是可重复的;但老实说。。。对于固定的三重存储,我真诚地怀疑DFA是否会在查询之间返回不同的blanknode排序。有什么好主意吗?

您不能在SPARQL中选择“n”个空白节点,原因有两个:

  • RDF模型是一个集合:三元组是无序的
  • 空白节点表示没有标识符的资源,这意味着它无法(直接)寻址/标识
  • 在RDF/SPARQL中,您以一种间接的方式处理空白节点:而不是试图直接寻址它们(正如我们在上面看到的,这是不可能的,因为空白节点的定义是它没有标识符),而是查看将它们连接到其他资源的事物,即它们所涉及的语句。毕竟,这些语句给空白节点的上下文含义。 在您的例子中:
    \ub1
    和其他两个空白节点之间的区别在于它们扮演subject角色的语句。因此,要在SPARQL中查询主题为
    :b1
    的三元组,您应该查看数据并看到,
    \ub1
    唯一地有一个属性
    :p3
    ,其值为
    :cantaloupe
    。您可以这样查询:

       CONSTRUCT { ?s ?p ?o }
       WHERE { :Foo :p ?s .
               ?s :p3 :cantaloupe ;
                  ?p ?o .
       }
    
    另一方面:几个SPARQL引擎实现提供了一些功能来解决空白节点没有(全局)标识符的问题。在许多情况下,它们引入了一些非标准语法扩展或自定义函数,允许您在SPARQL查询中直接寻址空白节点。我想强调的是,这是非标准的,不太可能跨不同的端点工作,因此最好避免

    如果你发现你真的无法工作而不必直接寻址你的空节点,那么你应该考虑不要在你的数据中使用空白节点,而是为这些东西创建合适的IRIS。p> UPDATE您对该问题的更新基本上是这样问的:“我可以利用SPARQL未命名的特定实现中的一些未记录的功能来执行严格来说不合法的查询,或者不保证给出我想要的结果,并且不受惩罚吗?”该问题的答案是:可能是的,但这取决于您使用的是哪种SPARQL实现,这是一个非常糟糕的主意,因为上面我已经给出了所有的理由

    实际上,许多(大多数?)TripleStore会在查询之间以相同的顺序返回相同的结果,尽管这并不能保证(我强调得不够多),而且您真的不应该依赖它。当然,您可以通过在查询中使用
    orderby
    子句来获得有序查询结果,但在这种情况下,这没有帮助,因为SPARQL中未定义空白节点的相对顺序(因此,查询引擎可以按照它认为合适的任何顺序自由返回
    \ub1
    \ub2
    ,即使存在
    order BY
    子句)。更糟糕的是:虽然您的输入RDF文件可能包含空白节点标识符
    \uB1
    \uB2
    ,但SPARQL查询不一定会返回这些标识符。许多TripleStore用内部生成的ID替换空白节点标识符,而SPARQL查询也同样可能返回
    \uID:genid-908c909eacc4b6da3d3059e18706d68-b1
    而不是简单的
    \uB1

    和即使你能可靠地得到空白节点ID:你要怎么处理它?一个空白节点是空白的。它携带的ID只用于内部簿记的目的——你不能使用空白节点进一步查询。

    相信我:这是个坏主意。如果你不能改变数据,请依赖那些连接空白节点并查询这些属性的属性。

    我知道,叹息……但是谢谢你花时间给其他人写这个。我已经更新了我的问题。