SPARQL 查询在 Fuseki 中有效,但在 Jena TDB 中无效
SPARQL query works in Fuseki but not in Jena TDB
我将数据组织成多个图表。保存三元组的图表很重要。数据结构比较复杂,但可以这样简化:
我的商店包含蛋糕,其中有不同蛋糕类型的层次结构,<cake>
的所有子类
<http://example.com/a1> a <http://example.com/applecake>
<http://example.com/a2> a <http://example.com/rainbowcake>
...
根据用户在 UI 中创建它们的方式,它们最终会出现在不同的图表中。例如,如果用户 "bakes" 一个蛋糕,它进入 <http://example.com/homemade>
图表,如果他们 "buy" 一个,它进入 <http://example.com/shopbought>
图表。
当我从商店取回蛋糕时,我想知道每个蛋糕是自制的还是从商店购买的。这个没有属性,我想纯粹根据存储三元组的图来检索信息。
我已经尝试了多种方法来实现这一点,但是 none 其中的方法在 Jena TDB 中有效。问题是所有蛋糕都返回为 "shopbought"。然而,所有查询都在 Fuseki 中工作(在确切的 sae 数据集上),我想知道这是 TDB 错误还是有其他方法。以下是简化的查询(没有变化):
版本 1:
SELECT DISTINCT *
FROM <http://example.com/homemade>
FROM <http://example.com/shopbought>
FROM NAMED <http://example.com/homemade>
FROM NAMED <http://example.com/shopbought>
WHERE {
?cake rdf:type ?caketype .
?caketype rdfs:subClassOf* <cake>
{
GRAPH <http://example.com/homemade> { ?cake rdf:type ?typeHomemade }
} UNION {
GRAPH <http://example.com/shopbought> { ?cake rdf:type ?typeShopbought }
}
BIND(str(if(bound(?typeHomemade), true, false)) AS ?homemade)
}
版本 2:
SELECT DISTINCT *
FROM <http://example.com/homemade>
FROM <http://example.com/shopbought>
FROM NAMED <http://example.com/homemade>
FROM NAMED <http://example.com/shopbought>
WHERE {
?cake rdf:type ?caketype .
?caketype rdfs:subClassOf* <cake>
GRAPH ?g {
?cake rdf:type ?caketype .
}
BIND(STR(IF(?g=<http://example.com/homemade>, true, false)) AS ?homemade)
}
知道为什么这在 Fuseki 中有效但在 TDB 中无效吗?
编辑:
我开始认为它与 GRAPH 关键字有关。这里有一些更简单的查询(在 Fuseki 和 tdbquery 中工作)和我使用 Jena API:
得到的结果
SELECT * WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }}
0 个结果
SELECT * WHERE { GRAPH ?g { ?s ?p ?o }}
0 个结果
SELECT * FROM <http://example.com/homemade> WHERE { ?s ?p ?o }
x 结果
SELECT * FROM <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }}
0 个结果
SELECT * FROM NAMED <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }}
0 个结果
好的,所以我的解决方案实际上与我执行查询的方式有关。我最初的想法是预过滤数据集,以便只在相关图形上执行查询(数据集包含许多图形,它们可能非常大,这会使查询 "everything" 变慢)。这可以通过将它们添加到 SPARQL 或直接在 Jena 中来完成(尽管这不适用于其他三元组存储)。然而,结合这两种方式 "to be on the safe side" 不起作用。
此查询在整个数据集上运行并按预期工作:
Query query = QueryFactory.create("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }", Syntax.syntaxARQ);
QueryExecution qexec = QueryExecutionFactory.create(query, dataset);
ResultSet result = qexec.execSelect();
同一查询只能在特定图上执行,无论是哪个图都不会给出任何结果:
//run only on one graph
Model target = dataset.getNamedModel("http://example.com/homemade");
//OR run on the union of all graphs
Model target = dataset.getNamedModel("urn:x-arq:UnionGraph");
//OR run on a union of specific graphs
Model target = ModelFactory.createUnion(dataset.getNamedModel("http://example.com/shopbought"), dataset.getNamedModel("http://example.com/homemade"), ...);
[...]
QueryExecution qexec = QueryExecutionFactory.create(query, target);
[...]
我的解决方法是现在总是查询整个数据集(它支持 SPARQL GRAPH 关键字很好)并且对于每个查询总是指定它应该 运行 避免查询整个数据集的图表。
不确定这是否是 Jena API
的预期行为
我将数据组织成多个图表。保存三元组的图表很重要。数据结构比较复杂,但可以这样简化:
我的商店包含蛋糕,其中有不同蛋糕类型的层次结构,<cake>
<http://example.com/a1> a <http://example.com/applecake>
<http://example.com/a2> a <http://example.com/rainbowcake>
...
根据用户在 UI 中创建它们的方式,它们最终会出现在不同的图表中。例如,如果用户 "bakes" 一个蛋糕,它进入 <http://example.com/homemade>
图表,如果他们 "buy" 一个,它进入 <http://example.com/shopbought>
图表。
当我从商店取回蛋糕时,我想知道每个蛋糕是自制的还是从商店购买的。这个没有属性,我想纯粹根据存储三元组的图来检索信息。
我已经尝试了多种方法来实现这一点,但是 none 其中的方法在 Jena TDB 中有效。问题是所有蛋糕都返回为 "shopbought"。然而,所有查询都在 Fuseki 中工作(在确切的 sae 数据集上),我想知道这是 TDB 错误还是有其他方法。以下是简化的查询(没有变化):
版本 1:
SELECT DISTINCT *
FROM <http://example.com/homemade>
FROM <http://example.com/shopbought>
FROM NAMED <http://example.com/homemade>
FROM NAMED <http://example.com/shopbought>
WHERE {
?cake rdf:type ?caketype .
?caketype rdfs:subClassOf* <cake>
{
GRAPH <http://example.com/homemade> { ?cake rdf:type ?typeHomemade }
} UNION {
GRAPH <http://example.com/shopbought> { ?cake rdf:type ?typeShopbought }
}
BIND(str(if(bound(?typeHomemade), true, false)) AS ?homemade)
}
版本 2:
SELECT DISTINCT *
FROM <http://example.com/homemade>
FROM <http://example.com/shopbought>
FROM NAMED <http://example.com/homemade>
FROM NAMED <http://example.com/shopbought>
WHERE {
?cake rdf:type ?caketype .
?caketype rdfs:subClassOf* <cake>
GRAPH ?g {
?cake rdf:type ?caketype .
}
BIND(STR(IF(?g=<http://example.com/homemade>, true, false)) AS ?homemade)
}
知道为什么这在 Fuseki 中有效但在 TDB 中无效吗?
编辑: 我开始认为它与 GRAPH 关键字有关。这里有一些更简单的查询(在 Fuseki 和 tdbquery 中工作)和我使用 Jena API:
得到的结果SELECT * WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }}
0 个结果
SELECT * WHERE { GRAPH ?g { ?s ?p ?o }}
0 个结果
SELECT * FROM <http://example.com/homemade> WHERE { ?s ?p ?o }
x 结果
SELECT * FROM <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }}
0 个结果
SELECT * FROM NAMED <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }}
0 个结果
好的,所以我的解决方案实际上与我执行查询的方式有关。我最初的想法是预过滤数据集,以便只在相关图形上执行查询(数据集包含许多图形,它们可能非常大,这会使查询 "everything" 变慢)。这可以通过将它们添加到 SPARQL 或直接在 Jena 中来完成(尽管这不适用于其他三元组存储)。然而,结合这两种方式 "to be on the safe side" 不起作用。
此查询在整个数据集上运行并按预期工作:
Query query = QueryFactory.create("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }", Syntax.syntaxARQ);
QueryExecution qexec = QueryExecutionFactory.create(query, dataset);
ResultSet result = qexec.execSelect();
同一查询只能在特定图上执行,无论是哪个图都不会给出任何结果:
//run only on one graph
Model target = dataset.getNamedModel("http://example.com/homemade");
//OR run on the union of all graphs
Model target = dataset.getNamedModel("urn:x-arq:UnionGraph");
//OR run on a union of specific graphs
Model target = ModelFactory.createUnion(dataset.getNamedModel("http://example.com/shopbought"), dataset.getNamedModel("http://example.com/homemade"), ...);
[...]
QueryExecution qexec = QueryExecutionFactory.create(query, target);
[...]
我的解决方法是现在总是查询整个数据集(它支持 SPARQL GRAPH 关键字很好)并且对于每个查询总是指定它应该 运行 避免查询整个数据集的图表。 不确定这是否是 Jena API
的预期行为