代码之家  ›  专栏  ›  技术社区  ›  Robin Keskisarkka

跨多个解决方案在构造中生成相同的空白节点

  •  2
  • Robin Keskisarkka  · 技术社区  · 7 年前

    我遇到过几次想在应用程序中使用空白节点的情况 CONSTRUCT

    @prefix : <http://example.org#> .
    
    :stephen_king a :Author ;
          :firstName "Stephen" ;
          :authorOf "The Shining", "Cujo".
    
    :stephen_hawking a :Author ;
          :firstName "Stephen" ;
          :authorOf "A Brief History of Time" . 
    
    :virginia_wolf a :Author ;
          :firstName "Virginia" ;
          :authorOf "Mrs Dalloway" . 
    

    例如,假设我想用作者的名字绑定所有书籍 Stephen

    PREFIX : <http://example.org#>
    CONSTRUCT {
       [ :containsBook ?book ]
    }
    WHERE {
       ?book ^:authorOf/:firstName "Stephen" .
    }
    

    将返回以下内容:

    [ :containsBook "The Shining" ] .
    [ :containsBook "A Brief History of Time" ] .
    [ :containsBook "Cujo" ] .
    

    [ :containsBook "The Shining" ;
      :containsBook "A Brief History of Time" ;
      :containsBook "Cujo" ] .
    

    1 回复  |  直到 7 年前
        1
  •  4
  •   Robin Keskisarkka    7 年前

    经过一段时间的思考,我想出了一些我认为是一个普遍的解决方案。虽然我还没有在许多SPARQL实现上尝试过,但如果您发现它不适合您,请提供反馈。基本上,在意识到SPARQL无法处理查询结果部分中的数据后,我们自然开始考虑将空白节点绑定到变量。那么,让我们试着像这样:

    PREFIX : <http://example.org#>
    CONSTRUCT {
       ?bnode :containsBook ?book
    }
    WHERE {
       ?book :hasAuthor/:firstName "Stephen" .
       BIND(BNODE() AS ?bnode)
    }
    

    不,那也不行。为什么?该查询评估整个查询,对于每个解决方案 BIND 函数将再次调用,我们将得到不同的空白节点。

    现在是诀窍。放置 绑定 组内查询的一部分。这样,由于SPARQL在变量作用域方面的工作方式,我们最终将得到一个连接 ?bnode 零件只能调用一次:

    PREFIX : <http://example.org#>
    CONSTRUCT {
       ?bnode :containsBook ?book 
    }
    WHERE {
       ?book :hasAuthor/:firstName "Stephen" .
       { BIND(BNODE() AS ?bnode) }
    }
    

    希望有人发现这和我一样有用。干杯