在 SPARQL 的 BIND 中使用时,VALUES 的位置似乎很重要
Position of VALUES seems to matter when used in BIND in SPARQL
我正在尝试了解 VALUES 在查询中的位置方面的行为。我们的想法是使用它来更轻松地对来自模板的 SPARQL 查询进行参数化。
对于大多数查询,它按预期工作,但我现在 运行 遇到了一个我不理解的情况。给定以下查询:
SELECT * WHERE {
# Hard coded version:
#BIND( (2020 - 2) AS ?year )
# Works as expected:
#VALUES ?startYear { 2020 }
#BIND( (?startYear -2 ) AS ?year )
# Does not work as expected:
# Year is "1" in Fuseki, empty in Stardog. The "-2" does not seem to have any effect in that scenario
BIND( (?startYear -2 ) AS ?year )
VALUES ?startYear { 2020 }
}
如评论中所见,最后一个不行。如果 VALUES 在 BIND 之前,一切似乎都符合预期。在 SPARQL 1.1 规范中,有一个示例,其中他们移动了 VALUES,但我找不到对我在这里看到的内容的解释。
当我在 BIND 中使用 VALUES 时,为什么它在查询末尾不起作用?在这种情况下,它在 FILTER 中运行良好。
重要的是 BIND 的位置,而不是 VALUES。 SPARQL 中的 BIND 总是关闭组图模式,即它位于它之前的同一 {}
块中的所有模式之上,请参阅 https://www.w3.org/TR/sparql11-query/#bind
如果您查看 http://www.sparql.org/query-validator.html:
处的查询结构(所谓的“代数”),就会变得很明显
SELECT *
WHERE {
VALUES ?startYear { 2020 }
BIND( (?startYear -2 ) AS ?year )
}
有这个代数:
9 (extend ((?year (- ?startYear 2)))
10 (table (vars ?startYear)
11 (row [?startYear 2020])
12 ))))
table
是您的 VALUES
,extend
是您的 BIND
。 BIND
是在 VALUES
之上计算的,因此 ?startYear
在减去 2 时有一个值。
SELECT *
WHERE {
BIND( (?startYear -2 ) AS ?year )
VALUES ?startYear { 2020 }
}
然而,有以下代数:
9 (join
10 (extend ((?year (- ?startYear 2)))
11 (table unit))
12 (table (vars ?startYear)
13 (row [?startYear 2020])
14 ))))
这里块中的 BIND
之前没有任何内容,因此您看到 table unit
作为它的参数(这就是所谓的空组)。它不绑定任何变量,因此 ?startYear
在计算 BIND
时没有值。 BIND 的结果是 then 与 VALUES
结合,但为时已晚,因为 - 2
已经发生了。
我总是建议使用该在线工具来检查查询的语义。
我正在尝试了解 VALUES 在查询中的位置方面的行为。我们的想法是使用它来更轻松地对来自模板的 SPARQL 查询进行参数化。
对于大多数查询,它按预期工作,但我现在 运行 遇到了一个我不理解的情况。给定以下查询:
SELECT * WHERE {
# Hard coded version:
#BIND( (2020 - 2) AS ?year )
# Works as expected:
#VALUES ?startYear { 2020 }
#BIND( (?startYear -2 ) AS ?year )
# Does not work as expected:
# Year is "1" in Fuseki, empty in Stardog. The "-2" does not seem to have any effect in that scenario
BIND( (?startYear -2 ) AS ?year )
VALUES ?startYear { 2020 }
}
如评论中所见,最后一个不行。如果 VALUES 在 BIND 之前,一切似乎都符合预期。在 SPARQL 1.1 规范中,有一个示例,其中他们移动了 VALUES,但我找不到对我在这里看到的内容的解释。
当我在 BIND 中使用 VALUES 时,为什么它在查询末尾不起作用?在这种情况下,它在 FILTER 中运行良好。
重要的是 BIND 的位置,而不是 VALUES。 SPARQL 中的 BIND 总是关闭组图模式,即它位于它之前的同一 {}
块中的所有模式之上,请参阅 https://www.w3.org/TR/sparql11-query/#bind
如果您查看 http://www.sparql.org/query-validator.html:
处的查询结构(所谓的“代数”),就会变得很明显SELECT *
WHERE {
VALUES ?startYear { 2020 }
BIND( (?startYear -2 ) AS ?year )
}
有这个代数:
9 (extend ((?year (- ?startYear 2)))
10 (table (vars ?startYear)
11 (row [?startYear 2020])
12 ))))
table
是您的 VALUES
,extend
是您的 BIND
。 BIND
是在 VALUES
之上计算的,因此 ?startYear
在减去 2 时有一个值。
SELECT *
WHERE {
BIND( (?startYear -2 ) AS ?year )
VALUES ?startYear { 2020 }
}
然而,有以下代数:
9 (join
10 (extend ((?year (- ?startYear 2)))
11 (table unit))
12 (table (vars ?startYear)
13 (row [?startYear 2020])
14 ))))
这里块中的 BIND
之前没有任何内容,因此您看到 table unit
作为它的参数(这就是所谓的空组)。它不绑定任何变量,因此 ?startYear
在计算 BIND
时没有值。 BIND 的结果是 then 与 VALUES
结合,但为时已晚,因为 - 2
已经发生了。
我总是建议使用该在线工具来检查查询的语义。