2017-05-26 63 views
1

我有我的数据组织在多个图表中。三联保存的图形很重要。数据结构是复杂的,但它可以简化如下:SPARQL查询在Fuseki中有效,但不在Jena中TDB

我的存储包含蛋糕,那里有不同的蛋糕类型的层次结构中,<cake>

<http://example.com/a1> a <http://example.com/applecake> 
<http://example.com/a2> a <http://example.com/rainbowcake> 
... 

所有子类根据他们得到如何通过创建用户在一个用户界面中,他们最终在一个不同的图表。例如,如果用户“烘烤”一块蛋糕,则它会在<http://example.com/homemade>图表中显示,如果他们“购买”一个,则会进入<http://example.com/shopbought>图表。

当我从商店取回蛋糕时,我想知道每个蛋糕是自制还是购物。没有这方面的财产,我想检索信息纯粹基于三重图存储在图表。

我已经尝试了各种方式实现这一目标,但没有一个在耶拿TDB工作。问题在于所有的蛋糕都是以“购物”的形式回归。所有的查询都在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) 
    } 

任何想法,为什么这部作品在定式,但不是在TDB?

编辑: 我开始认为它与GRAPH关键字有关。这里有一些更简单的查询(在定式和tdbquery工作),结果我得到使用耶拿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结果

+1

请看[1](https://stackoverflow.com/questions/18891690),[2](https://jena.apache.org/documentation/ tdb/dynamic_datasets.html),[3](https://jena.apache.org/documentation/tdb/datasets.html#special-graph-names)。 –

+0

斯坦尼斯拉夫是正确的。使用完整的URI作为图表名称。否则,这些可能会被解析为文件的默认位置等。 – AKSW

+0

我确实使用完整的URI,我只是缩短了它的示例,并使用方括号来表示它是完整的URI。我相应地更新了示例,使其更加清晰。 – casualcoder

回答

2

OK,所以我的解决方案实际上已经与我执行查询的方式做。我最初的想法是对数据集进行预过滤,以便在相关图表上执行查询(数据集包含许多图表,并且它们可能很大,这会使查询“一切”变慢)。这可以通过将它们添加到SPARQL中或直接在Jena中完成(尽管这不适用于其他三重商店)。然而,将这两种方式结合起来“在安全方面”是行不通的。

该查询运行在整个数据集和按预期工作:

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的预期行为