在跨多个解决方案的 CONSTRUCT 中生成相同的空白节点
Produce the same blank node in CONSTRUCT across multiple solutions
我曾多次遇到想在 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" .
}
会 return 是这样的:
[ :containsBook "The Shining" ] .
[ :containsBook "A Brief History of Time" ] .
[ :containsBook "Cujo" ] .
但期望的结果是:
[ :containsBook "The Shining" ;
:containsBook "A Brief History of Time" ;
:containsBook "Cujo" ] .
关于如何实现这一点有什么想法吗?
经过一段时间的思考,我想出了一些我认为是通用的解决方案。我还没有在许多 SPARQL 实现上尝试过它,所以如果您发现它不适合您,请提供反馈。基本上,在意识到我们无法对 SPARQL 如何处理查询结果部分中的数据做任何事情之后,我们自然而然地开始考虑将空白节点绑定到一个变量。所以,假设我们尝试这样的事情:
PREFIX : <http://example.org#>
CONSTRUCT {
?bnode :containsBook ?book
}
WHERE {
?book :hasAuthor/:firstName "Stephen" .
BIND(BNODE() AS ?bnode)
}
不,那也不行。这是为什么?查询评估整个查询,对于每个解决方案,将再次调用 BIND
函数,我们将以不同的空白节点结束。
技巧来了。将查询的 BIND
部分放在一个组中。这样,由于 SPARQL 在变量作用域方面的工作方式,我们将在 之后得到一个联接 查询已被评估,其中 ?bnode
部分将被调用只有一次:
PREFIX : <http://example.org#>
CONSTRUCT {
?bnode :containsBook ?book
}
WHERE {
?book :hasAuthor/:firstName "Stephen" .
{ BIND(BNODE() AS ?bnode) }
}
希望有人觉得这和我一样有用。干杯。
我曾多次遇到想在 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" .
}
会 return 是这样的:
[ :containsBook "The Shining" ] .
[ :containsBook "A Brief History of Time" ] .
[ :containsBook "Cujo" ] .
但期望的结果是:
[ :containsBook "The Shining" ;
:containsBook "A Brief History of Time" ;
:containsBook "Cujo" ] .
关于如何实现这一点有什么想法吗?
经过一段时间的思考,我想出了一些我认为是通用的解决方案。我还没有在许多 SPARQL 实现上尝试过它,所以如果您发现它不适合您,请提供反馈。基本上,在意识到我们无法对 SPARQL 如何处理查询结果部分中的数据做任何事情之后,我们自然而然地开始考虑将空白节点绑定到一个变量。所以,假设我们尝试这样的事情:
PREFIX : <http://example.org#>
CONSTRUCT {
?bnode :containsBook ?book
}
WHERE {
?book :hasAuthor/:firstName "Stephen" .
BIND(BNODE() AS ?bnode)
}
不,那也不行。这是为什么?查询评估整个查询,对于每个解决方案,将再次调用 BIND
函数,我们将以不同的空白节点结束。
技巧来了。将查询的 BIND
部分放在一个组中。这样,由于 SPARQL 在变量作用域方面的工作方式,我们将在 之后得到一个联接 查询已被评估,其中 ?bnode
部分将被调用只有一次:
PREFIX : <http://example.org#>
CONSTRUCT {
?bnode :containsBook ?book
}
WHERE {
?book :hasAuthor/:firstName "Stephen" .
{ BIND(BNODE() AS ?bnode) }
}
希望有人觉得这和我一样有用。干杯。