12

可能很容易回答这个问题,但我什至不知道如何制定谷歌查询来找到它。

我正在针对包含空白节点的数据集编写 SPARQL 构造查询。所以如果我做一个像这样的查询

CONSTRUCT {?x ?y ?z .} WHERE {?x ?y ?z .}

那么我的结果之一可能是:

nm:John nm:owns _:Node

如果所有的都是一个问题

_:Node nm:has nm:Hats

三元组也不会以某种方式进入查询结果(因为我使用的一些解析器,比如 Python 的 rdflib 真的不喜欢悬空的 bnodes)。

有没有办法编写我的原始 CONSTRUCT 查询以递归地添加附加到任何 bnode 结果的所有三元组,以便在我的新图中没有任何 bnode 悬空?

4

3 回答 3

11

递归是不可能的。我能想到的最接近的是SPARQL 1.1 属性路径(注意:该版本已过时)但 bnode 测试不可用(afaik)。

您可以删除带有尾随 bnode 的语句:

CONSTRUCT {?x ?y ?z .} WHERE 
{
  ?x ?y ?z .
  FILTER (!isBlank(?z))
}

或者试试你的运气来获取下一点:

CONSTRUCT {?x ?y ?z . ?z ?w ?v } WHERE 
{
  ?x ?y ?z .
  OPTIONAL {
    ?z ?w ?v
    FILTER (isBlank(?z) && !isBlank(?v))
  }
}

(最后一个查询是相当惩罚,顺便说一句)

使用 可能会更好DESCRIBE,它通常会跳过 bnode。

于 2012-03-20T10:19:50.793 回答
3

正如 user205512 所建议的那样,递归执行该抓取是不可能的,并且正如他们所指出的那样,使用 optional(s) 将任意级别降低到您的数据中获取节点在除了非平凡大小的数据库之外是不可行的。

Bnodes 本身是本地范围的,对于结果集或文件。无法保证您从解析或结果集中获得的 BNode 与数据库中使用的 id 相同(尽管某些数据库确实为查询结果保证了这一点)。此外,像 "select ?s where { ?s ?p _:bnodeid1 }" 这样的查询与 "select ? where { ?s ?p ?o }" 相同——注意在这种情况下 bnode 被视为变量,而不是“带有 id 'bnodeid1' 的东西” 这种设计的怪癖使得查询 bnode 变得很困难,所以如果你可以控制数据,我建议不要使用它们。为原本是 bnodes 的东西生成名称并不难,并且命名资源 v. bnodes 在查询期间不会增加开销。

这并不能帮助您递归并获取数据,但为此,我不建议您进行此类一般查询;它们不能很好地扩展,并且通常返回比您想要或需要的更多。我建议你做更多的定向查询。您最初的构造查询将拉下整个数据库的内容,这通常不是您想要的。

最后,虽然 describe 很有用,但没有标准的实现;SPARQL 规范没有定义任何特定的行为,因此它返回的内容留给数据库供应商,并且可能有所不同。如果您计划在您的应用程序中尝试不同的数据库,这可能会降低您的代码的可移植性。如果你想要一个无法描述的特定行为,你最好自己实现它。为资源做简洁的有界描述是一段简单的代码,尽管你可能会在 Bnodes 周围遇到一些令人头疼的问题。

于 2012-03-20T15:32:35.183 回答
1

关于使用 ruby​​ RDF.rb 库,它允许在 RDF::Graph 对象上使用重要的便捷方法进行 SPARQL 查询,以下应该扩展空白节点。

rdf_type = RDF::SCHEMA.Person # for example
rdf.query([nil, RDF.type, rdf_type]).each_subject do |subject|
  g = RDF::Graph.new
  rdf.query([subject, nil, nil]) do |s,p,o|
    g << [s,p,o]
    g << rdf_expand_blank_nodes(o) if o.node?
  end
end

def rdf_expand_blank_nodes(object)
  g = RDF::Graph.new
  if object.node?
    rdf.query([object, nil, nil]) do |s,p,o|
      g << [s,p,o]
      g << rdf_expand_blank_nodes(o) if o.node?
    end
  end
  g
end
于 2015-02-21T03:39:44.453 回答