使用Blank节点的Sparql查询可能很复杂

Com*_*eto 6 rdf semantic-web sparql linked-data blank-nodes

我读过这篇博客文章,RDF模型的问题:空白节点,并且提到使用空白节点会使数据处理复杂化.

您能举例说明为什么使用空白节点很难执行SPARQL查询吗?我不明白空白节点的复杂性.你能解释一下存在变量的含义和语义吗?我不清楚RDF语义建议书1.5中给出的解释.空白节点作为存在变量.

Jos*_*lor 11

存在变量

在(一阶)谓词演算中,有存在量化,它允许我们对存在的事物做出断言,而不是说(或者可能知道)我们实际谈论的域中的哪些特定个体.例如,一句话就像

hasUserId(JoshuaTaylor,1281433)

需要判刑

X .hasUserId(X,1281433)

当然,有很多情况下第二句可能是真的,而第一句是真的.从这个意义上讲,第二句话给我们提供的信息少于第一句.同样重要的是要注意,第二句中的变量x没有提供任何方法来找出话语域中哪个元素实际上具有给定的userId.它也没有声称只有一个具有给定用户ID的东西.为了更清楚,我们可以使用一个例子:

ÿ .hasAge(Y,29)

这可能是真的,因为某人或某事出有年龄29.请注意,我们不能谈论Ÿ是29岁,虽然个人,因为可能有很多很多.所有这句话告诉我们的是,至少有一个.

尽管我们在两个句子中使用了不同的变量,但没有什么可以说具有指定属性的个体可能不一样.这在嵌套量化中尤为重要,例如,

X .∃ Ý .likes(X,ÿ)

这句话可能是真的,因为域中有一个人喜欢自己.仅仅因为xy在句子中有不同的名称并不意味着它们可能不会引用同一个体.

空白节点作为存在变量

RDF语义中定义了一个定义的RDF蕴涵模型.这在另一个Stack Overflow问题RDF Graph Entailment中有更多描述.这个想法是RDF图对图中提到的空白节点进行了大量的存在量化处理.例如,如果图中的三元组是t 1,...,t n,并且出现在这些三元组中的空白节点是b 1,...,b m,则图形是公式:

∃b 1,...,B .(T 1 ∧...∧吨Ñ)

基于对上述存在变量的讨论,请注意,这意味着数据中的空白节点可能引用域的相同元素或不同的元素,并且不需要只有一个元素可以取代空白节点.这意味着,当以这种方式解释时,具有空白节点的图形提供的信息比您预期的要少得多.

真实数据中的空白节点

现在,如果人们使用空白节点作为存在变量,上面的讨论很有.在许多情况下,作者认为它们更像是匿名的,但却是明确而独特的对象.例如,如果我们随便写

@prefix : <https://stackoverflow.com/q/20629437/1281433/> .

:Carol :hasAddress [ :hasNumber 4222 ;
                     :hasStreet :Clinton_Way ] .
Run Code Online (Sandbox Code Playgroud)

我们很可能是想说,有一个单一的地址在那里与指定的性质,而是根据RDF蕴涵的模式,这不是我们在做什么.

在实践中,这不是一个问题,因为我们通常不使用RDF蕴涵.什么虽然一个问题是,由于空变量的作用域是本地的一个图,我们不能运行针对端点要求卡罗尔的地址的SPARQL查询并取回一个IRI,我们可以重用.如果我们运行这样的查询:

prefix : <https://stackoverflow.com/q/20629437/1281433/>

construct {
  :Mike :hasAddress ?address
}
where {
  :Carol :hasAddress ?address
}
Run Code Online (Sandbox Code Playgroud)

然后我们得到以下(无用的)图表:

@prefix :      <https://stackoverflow.com/q/20629437/1281433/> .

:Mike   :hasAddress  []  .
Run Code Online (Sandbox Code Playgroud)

我们无法获得有关该地址的更多信息,因为我们现在拥有的只是一个空白节点.如果我们使用过IRI,例如,

@prefix : <https://stackoverflow.com/q/20629437/1281433/> .

:Carol :hasAddress :address1267389 .
:address1267389 :hasNumber 4222 ;
                :hasStreet :Clinton_Way .
Run Code Online (Sandbox Code Playgroud)

然后查询会产生更有帮助的东西:

@prefix :      <https://stackoverflow.com/q/20629437/1281433/> .

:Mike   :hasAddress  :address1267389 .
Run Code Online (Sandbox Code Playgroud)

为什么这更有用?第一种情况就像拥有数据一样

∃x.(hasAddress(Carol,x)∧hasNumber(x,4222)∧hasStreet(x,ClintonWay))

并得到一个结果

∃y.hasAddress(Mike,y)

当然,迈克和卡罗尔可能有相同的地址,但从这些句子中无法确切知道.拥有像这样的数据会更有帮助

hasAddress(Carol,address1267389)
hasNumber(address1267389,4222)
hasStreet(address1267389,ClintonWay))

并得到一个结果

hasAddress(麦克,address1267389)

从这里,你知道他们有相同的地址,你可以询问它.

结论

这对您的数据及其消费者的影响程度取决于典型的用例.对于自动构建的图形,可能很难事先知道您需要稍后引用的数据类型,因此为尽可能多的资源生成IRI是个好主意.由于IRI是自由形式的,因此通常不会太难.例如,如果你有一些明智的"基础"IRI,例如,

http://example.org/myData/
Run Code Online (Sandbox Code Playgroud)

然后你可以轻松附加后缀来识别你的资源.例如,

http://example.org/myData/addresses/addr1
http://example.org/myData/addresses/addr2
http://example.org/myData/addresses/addr3
http://example.org/myData/individuals/ind34
http://example.org/myData/individuals/ind35
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常有帮助的答案,对我来说清除了很多。这意味着,即使 RDF 本质上是语义 Web 环境中不同系统和应用程序之间的通信手段,但空白节点永远不能成为这种通信的单元。您可以将 IRI 从一个组件或软件系统传递到另一个组件或软件系统,但不能传递空白节点。因此,如果这些系统或代理希望有效通信,则必须强制执行严格作为存在变量的空白节点的语义。 (2认同)