2017-05-26 8 views
1

Ich habe meine Daten in mehreren Diagrammen organisiert. Die Grafik, in der ein Triple gespeichert wird, ist wichtig. Die Datenstruktur ist kompliziert, aber es kann wie folgt vereinfacht werden:SPARQL Abfrage funktioniert in Fuseki aber nicht in Jena TDB

Mein Speicher enthält Kuchen, wo eine Hierarchie von verschiedenen Kuchen Typen es gibt, alle Subklassen von <cake>

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

Je nachdem, wie sie durch eine erstellt erhalten Benutzer in einer Benutzeroberfläche, landen sie in einem anderen Diagramm. Wenn zum Beispiel der Benutzer einen Kuchen "backt", geht es in die <http://example.com/homemade> Grafik, wenn sie einen "kaufen", geht es in den <http://example.com/shopbought> Graph.

Wenn ich meine Kuchen aus dem Laden holen, möchte ich für jeden Kuchen wissen, ob es hausgemacht oder shopbought ist. Es gibt keine Eigenschaft dafür, ich möchte die Informationen rein basierend auf der Grafik abrufen, in der das Triple gespeichert ist.

Ich habe verschiedene Möglichkeiten versucht, dies zu erreichen, aber keine von ihnen funktioniert in Jena TDB. Das Problem ist, dass alle Kuchen als "shopbought" zurückkommen. Alle Abfragen funktionieren jedoch in Fuseki (auf dem genauen SAE-Datensatz) und ich fragte mich, ob dies ein TDB-Fehler ist oder ob es einen anderen Weg gibt. Hier sind die vereinfachte Abfragen (ohne Variationen):

Version 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) 
} 

Version 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) 
    } 

Irgendwelche Ideen, warum dies in Fuseki funktioniert aber nicht in TDB?

Bearbeiten: Ich fange an zu denken, dass es etwas mit dem Schlüsselwort GRAPH zu tun hat. Hier sind einige viel einfacher Abfragen (die in Fuseki und tdbquery arbeiten) und die Ergebnisse, die ich erhalten mit der Jena API:

SELECT * WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }} 

0 Ergebnisse

SELECT * WHERE { GRAPH ?g { ?s ?p ?o }} 

0 Ergebnisse

SELECT * FROM <http://example.com/homemade> WHERE { ?s ?p ?o } 

x Ergebnisse

SELECT * FROM <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }} 

0 Ergebnisse

SELECT * FROM NAMED <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }} 

0 Ergebnisse

+1

Schauen Sie sich [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

Stanislav hat Recht. Verwenden Sie vollständige URIs für die Diagrammnamen. Andernfalls werden diese möglicherweise in den Standardspeicherort der Datei usw. aufgelöst. – AKSW

+0

Ich benutze volle URIs, ich habe es einfach für das Beispiel gekürzt und die Klammern verwendet, um anzuzeigen, dass es sich um einen vollständigen URI handelt. Ich habe mein Beispiel entsprechend aktualisiert, um es klarer zu machen. – casualcoder

Antwort

2

OK so meine Lösung tatsächlich zu tun mit der Art und Weise habe ich die Abfrage ausgeführt wird. Meine anfängliche Idee war, das Dataset vorzufiltern, so dass eine Abfrage nur auf den relevanten Graphen ausgeführt wird (das Dataset enthält viele Graphen und sie können ziemlich groß sein, was die Abfrage "alles" langsam machen würde). Dies kann entweder durch Hinzufügen zu SPARQL oder direkt in Jena geschehen (obwohl dies bei anderen Triple Stores nicht funktionieren würde). Beide Wege zu kombinieren, aber "auf der sicheren Seite" zu sein, funktioniert nicht.

Diese Abfrage wird auf dem gesamten Datensatz und funktioniert wie erwartet:

Query query = QueryFactory.create("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }", Syntax.syntaxARQ); 
QueryExecution qexec = QueryExecutionFactory.create(query, dataset); 
ResultSet result = qexec.execSelect(); 

Die gleiche Abfrage nur auf einem bestimmten Diagramm ausgeführt werden kann, wo es keine Rolle spielt, welcher Graph, der ist, gibt es nicht alle Ergebnisse:

//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); 
[...] 

Meine Abhilfe den gesamten Datensatz und für jede Abfrage immer die Diagramme, auf denen sollte es laufen angeben (die die SPARQL GRAPH Schlüsselwort fein unterstützt) bis jetzt immer Abfrage war zu vermeiden, den gesamten Datensatz abfragen . Nicht sicher, ob dies erwartetes Verhalten für die Jena-API ist

Verwandte Themen