2016-03-24 12 views
1

Ich machte Sparql Abfrage für Gruppierung Ergebnis und führte die Abfrage über den SPARQL-Endpunkt http://glam.iptime.org/sparql.Warum erhält meine Sparql-Abfrage kein Ergebnis?

Aber ich habe keine Ergebnisse und keine Fehlermeldungen.

Abfrage ist wie folgt.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX owl: <http://www.w3.org/2002/07/owl#> 
PREFIX cfo: <http://lod.culture.go.kr/ontology/> 
PREFIX dc: <http://purl.org/dc/elements/1.1/> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 

SELECT ?age ?typeName (count(?s) as ?cnt) 
WHERE { 
{ 
select * where { 
?s rdf:type cfo:CulturalObject. 
?s rdfs:label ?label. 
?s cfo:temporal ?time. 
?time cfo:begin ?begin.  

BIND (STRDT(replace(?begin, 'BC', '-'), xsd:float) as ?year). 
BIND(IF(?year > 1897, "modern", IF(?year > 1392, "chosun", IF(?year > 918, "goryeo", IF(?year > 700, "north_south", IF(?year > -58, "three_states", "ancient"))))) as ?age). 

?s dc:type ?type. 
?type rdfs:label ?typeName. 
} 
} 
FILTER(BOUND(?age)). 
} 
GROUP BY ?age ?typeName 
LIMIT 100 

Hat meine Sparql-Abfrage ein Problem? Welches Problem hat es?

Ich denke, dass Sparql Abfrage Deklaration Reihenfolge ist falsch. Irgendeine andere Meinung?

+0

Niemand kann ohne ein Gefühl für die Daten, die Sie abfragen, sagen. Es kann sein, dass SPARQL vollkommen gültig ist, aber Ihre Daten nicht übereinstimmen. Ein paar Tipps: Schauen Sie sich COALESCE an, anstatt mehrere IFs, und die Sub-Auswahl ist fast immer ein Fehler, es sei denn, die Subselect wird zur Berechnung von Aggregaten verwendet. – scotthenninger

+2

Auch nicht klar, was mit "Abfrage Deklarationsreihenfolge ist falsch" gemeint ist. SPARQL ist eine deklarative Sprache und daher hat die Reihenfolge der Abfrageklauseln keine Auswirkungen auf das Ergebnis. Die Reihenfolge kann sich auf die Abfrageeffizienz auswirken, aber das ist ein anderes Thema. – scotthenninger

Antwort

6

Anstatt die Arbeit für Sie zu erledigen und den Endpunkt mit Ihrer Abfrage zu treffen, möchte ich Ihnen sagen, wie Sie das Problem angehen. Grundsätzlich bauen Sie die Abfrage pedantisch auf. Beginnen Sie mit einem einzelnen Dreifachmuster. Führen Sie die Abfrage - LIMIT ist Ihr Freund hier. Dann füge das nächste Dreifachmuster hinzu. Experimentieren Sie mit den Ergebnissen, während Sie gehen.

So ist die erste Abfrage würde einfach sein:

SELECT * 
WHERE { 
    ?s a cfo:CulturalObject. 
} LIMIT 100 

dass ausführen, überprüfen, ob sie die Ergebnisse bekommt. Nächste Abfrage lautet:

SELECT * 
WHERE { 
    ?s a cfo:CulturalObject. 
    ?s rdfs:label ?label. 
} LIMIT 100 

Sagen wir, dies schlägt fehl - Sie erhalten keine Ergebnisse. Vielleicht haben sie stattdessen skos:prefLabel verwendet. SPARQL ist eine sehr Sondierungs Sprache, so dass Sie das folgende versuchen könnte:

SELECT * 
WHERE { 
    ?s a cfo:CulturalObject. 
    ?s ?p ?o 
} LIMIT 100 

Überprüfen Sie die Werte von ?p und ?o zu sehen, wie die Daten tatsächlich strukturiert ist. Erhöhe die LIMIT, um ein bisschen mehr zu sehen. Verwenden Sie die Ergebnisse, um das nächste Dreifachmuster zu erstellen.

Am Ende geht es nur darum, die Daten zu erkunden, und im Gegensatz zu OWL oder ähnlichen Abfragesprachen benötigen Sie fast keine Kenntnis der Daten, um eine erfolgreiche Abfrage auszuführen. In der Tat, nur damit Sie wissen, wird die folgende Abfrage IMMER Ergebnisse liefern, es sei denn, der Datenspeicher leer ist:

SELECT ?s ?p ?o 
WHERE { 
    ?s ?p ?o . 
} LIMIT 1000 

Wie im Kommentar angegeben, sub-select ist fast immer ein Fehler, es sei denn, die Unterauswahl ist Rechenaggregate. Es ist ein SPARQL-Anti-Pattern, das ich oft sehe, und ich kann nur davon ausgehen, dass es einige Beispiele gibt, die Sub-Selects falsch verwenden. Nur etwas, auf das man achten sollte.

2

Einige der Jahre in den Daten enthalten einige Zeichen, die Dinge zu brechen scheinen. Eine Lösung dieses Problems, wenn Sie Zeilen ausschließen möchten, die ein leeres ?age haben, ist zum Ausfiltern von Werten, die solche die Zeichen mit einem regex, etwa so: FILTER(REGEX(?begin, "^(BC)?[0-9]+$"))

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX cfo: <http://lod.culture.go.kr/ontology/> 
PREFIX dc: <http://purl.org/dc/elements/1.1/> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 

SELECT ?age ?typeName (count(?s) as ?cnt) WHERE { 
    ?s rdf:type cfo:CulturalObject. 
    ?s rdfs:label ?label. 
    ?s cfo:temporal ?time. 
    ?time cfo:begin ?begin. 
    # Filter the dates 
    FILTER(REGEX(?begin, "^(BC)?[0-9]+$")) 
    ?s dc:type ?type. 
    ?type rdfs:label ?typeName. 
    BIND (STRDT(replace(?begin, 'BC ', '-'), xsd:integer) as ?year). 
    BIND(IF(?year > 1897,"modern", 
      IF(?year > 1392, "chosun", 
       IF(?year > 918, "goryeo", 
       IF(?year > 700, "north_south", 
        IF(?year > -58, "three_states", 
         "ancient"))))) as ?age) 
} 
GROUP BY ?age ?typeName 
LIMIT 100 

Sie brauchen nicht auf die Unterabfrage Sie haben in Ihrer Abfrage.

Die folgende Abfrage ruft alle cfo:begin Werte ab, die Nicht-Wortzeichen enthalten (einschließlich der problematischen Zeichen).

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX cfo: <http://lod.culture.go.kr/ontology/> 

SELECT ?begin (count(?s) as ?cnt) WHERE 
{ 
    ?s cfo:temporal ?time. 
    ?time cfo:begin ?begin. 
    FILTER(REGEX(?begin, "\\W")) 
} 
GROUP BY ?begin 
LIMIT 100 

By the way, empfehle ich YASGUI für Abfragen auszuprobieren, wenn Sie nicht mit ihm bereits vertraut sind.

Verwandte Themen