我有以下联合 SPARQL 查询,它在 TopBraid Composer 免费版(5.1.4 版)中按预期工作,但在 Apache Fuseki(2.3.1 版)中不起作用:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX movie: <http://data.linkedmdb.org/resource/movie/>
PREFIX dcterms: <http://purl.org/dc/terms/>
SELECT ?s WHERE {
SERVICE <http://data.linkedmdb.org/sparql> {
<http://data.linkedmdb.org/resource/film/1> movie:actor ?actor .
?actor movie:actor_name ?actorName .
}
SERVICE <http://dbpedia.org/sparql?timeout=30000> {
?s ?p ?o .
FILTER(regex(str(?s), replace(?actorName, " ", "_"))) .
}
}
我监视在后台执行的子 SPARQL 查询,并注意到 TopBraid 正确地执行了对http://dbpedia.org/sparql端点的以下查询:
SELECT *
WHERE
{ ?s ?p ?o
FILTER regex(str(?s), replace("Paul Reubens", " ", "_"))
}
而 Apache Fuseki 执行以下子查询:
SELECT *
WHERE
{ ?s ?p ?o
FILTER regex(str(?s), replace(?actorName, " ", "_"))
}
注意区别;TopBraid 将变量 ?actorName 替换为特定值“Paul Reubens”,而 Apache Fuseki 没有。这会导致来自http://dbpedia.org/sparql端点的错误,因为 ?actorName 在结果集中使用但未分配。
这是 Apache Fuseki 中的错误还是 TopBraid 中的功能?如何让 Apache Fuseki 正确执行这个联合查询。
更新 1:进一步阐明 TopBraid 和 Apache Fuseki 之间的行为差异。TopBraid 首先执行linkedmdb.org 子查询,然后为linkedmdb.org 查询的每个结果执行dbpedia.org 子查询)(并将?actorName 替换为linkedmdb.org 查询的结果)。我假设 Apache Fuseki 的行为类似,但是对 dbpedia.org 的第一个子查询失败(因为 ?actorName 在结果集中使用但未分配),因此它不会继续。但现在我不确定它是否真的要多次执行对 dbpedia.org 的子查询,因为它永远不会到达那里。
更新 2:我认为 TopBraid 和 Apache Fuseki 都使用 Jena/ARQ,但我注意到在 TopBraid 的堆栈跟踪中,包名称类似于 com.topbraid.jena.*,这可能表明他们使用的是 Jena/ARQ 的修改版本?
更新 3: Joshua Taylor 在下面说:“您肯定不会期望为每个服务块执行第二个服务块吗?”。TopBraid 和 Apache Fuseki 都使用此方法进行以下查询:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX movie: <http://data.linkedmdb.org/resource/movie/>
PREFIX dcterms: <http://purl.org/dc/terms/>
SELECT ?film ?label ?subject WHERE {
SERVICE <http://data.linkedmdb.org/sparql> {
?film a movie:film .
?film rdfs:label ?label .
?film owl:sameAs ?dbpediaLink
FILTER(regex(str(?dbpediaLink), "dbpedia", "i"))
}
SERVICE <http://dbpedia.org/sparql> {
?dbpediaLink dcterms:subject ?subject
}
}
LIMIT 50
但我同意原则上他们应该执行这两个部分并加入它们,但也许出于性能原因,他们选择了不同的策略?
此外,请注意上述查询如何在 Apache Fuseki 上运行,而本文的第一个查询则不然。因此,在这种特殊情况下,Apache Fuseki 实际上与 TopBraid 的行为类似。与在 FILTER 正则表达式函数中使用三重模式中的字符串变量 (?actorName ) 相比,它似乎与在两个三重模式中使用URI变量 (?dbpediaLink)(在 Fuseki 中有效)有关(在 Fuseki 中无效) )。