2017-10-16 7 views
0

Ich habe Schwierigkeiten, eine korrekte SPARQL-Abfrage zu erstellen, die das richtige Format erzeugen wird, damit ich darin Protege öffnen kann. Unsere Ontologie dreht sich um Cocktails, wir möchten alle DBPedia Cocktails in unserer Datenbank haben, einschließlich der Zutaten (dbp:ingredients) und des Rezepts (dbp:prep). Der Cocktail in der Datenbank funktioniert gut, aber die Zutaten und das Rezept nicht. Ich habe jetzt die folgende Abfrage:?Literal als Betreff in SPARQL CONSTRUCT Abfrage

CONSTRUCT {?drink dct:subject ?category. 
?drink dbp:prep ?recipe. 
?drink dbp:ingredients ?ingredients. 
?drink rdf:type owl:NamedIndividual . 
?category rdf:type owl:Class. 
dct:subject rdf:type owl:ObjectProperty. 
dbp:prep rdf:type owl:ObjectProperty. 
dbp:ingredient rdf:type owl:Objectproperty. 
} 
WHERE { 
?drink dct:subject ?category. 
?drink dbp:prep ?recipe. 
?drink dbp:ingredients ?ingredients.} 

Da Zutaten und Rezept sind jetzt nicht erklärt, es zeigt nicht im Einzelnen Tab in Protege. Aber wenn ich dies den CONSTRUCT Teil der Abfrage hinzu:

?recipe rdf:type owl:NamedIndividual. 
?ingredients rdf:type owl:NamedIndividual. 

Ich erhalte eine Fehlermeldung:

Virtuoso RDF01 Error Bad variable value in CONSTRUCT: "*5 cL vodka *10 cL orange juice" (tag 246 box flags 0) is not a valid subject, only object of a triple can be a literal

Ich denke, weil die Vorbereitung und Zutaten auf dbpedia sind nur eine Zeichenfolge, keine verknüpften Daten. Wie aber mache ich das so, dass es in Protege angezeigt wird?

+1

Kurz gesagt, Literale können nicht Gegenstand sein. Sie sollten Dateneigenschaften deklarieren - keine Objekteigenschaften - und entsprechende Literale als Werte definieren. Es scheint schwierig zu sein, diese Literale zu analysieren, um Objekte zu extrahieren. Wahrscheinlich könnten Sie Wikidata für strukturiertere Informationen zu Cocktails abfragen (mit föderierten Abfragen zu DBpedia, wenn Sie Textbeschreibungen behalten möchten). BTW: https://stackoverflow.com/a/44227937/7879193 –

+0

So ist es unmöglich, einen Literal als eine Eule zu deklarieren: NamedIndividual? Oder vielleicht eine Möglichkeit, das Literal in der Abfrage so zu konvertieren, dass es möglich ist? –

+0

Ein IRI wird als eindeutiger Bezeichner eines 'Owl: NamedIndividual' verwendet. – AKSW

Antwort

1

Es ist nicht möglich, ein Literal als Betreff eines RDF-Tripel zu verwenden. Stattdessen könnte das Erstellen einer Ressource für Rezept und Zutaten + Anfügen der Zeichenfolgenwerte als rdfs:comment (oder möglicherweise rdfs:label) eine Problemumgehung sein. Es funktioniert wie folgt:

CONSTRUCT { 
?drink dct:subject ?category. 
?drink dbp:prep ?recipe. 
?drink dbp:ingredients ?ingredients. 
?drink rdf:type owl:NamedIndividual . 
?category rdf:type owl:Class. 
dct:subject rdf:type owl:ObjectProperty. 
dbp:prep rdf:type owl:ObjectProperty. 
dbp:ingredients rdf:type owl:Objectproperty. 
# add string values as rdfs:comment 
?recipe rdfs:comment ?recipe_str . 
?ingredients rdfs:comment ?ingredients_str 
} 
WHERE { 
?drink dct:subject ?category. 
?drink dbp:prep ?recipe_str. 
?drink dbp:ingredients ?ingredients_str. 
BIND(URI(CONCAT("http://dbpedia.org/resource/recipe", MD5(STR(?recipe_str)))) as ?recipe) 
BIND(URI(CONCAT("http://dbpedia.org/resource/ingredients", MD5(STR(?ingredients_str)))) as ?ingredients) 
} 

Hinweis, es wäre irgendwie fehl, wenn das Rezept (bzw. Zutaten.) Ist bereits eine Ressource. Es gilt nicht für dbp:prep und dbp:ingredients auf DBpedia, aber im Allgemeinen, wenn Sie nicht sicher sind, und Sie haben einige rdf:Property, die tatsächlich sowohl Ressourcen als auch Literale erlaubt, müssen Sie dies richtig behandeln, z. unter Verwendung des IF-ELSE Konstrukt:

BIND(IF(isLiteral(?recipe_str), URI(CONCAT("http://dbpedia.org/resource/recipe", MD5(STR(?recipe_str)))), ?recipe_str) as ?recipe) 
BIND(IF(isLiteral(?ingredients_str), URI(CONCAT("http://dbpedia.org/resource/ingredients", MD5(STR(?ingredients_str)))), ?ingredients_str) as ?ingredients) 

und Sie würden auch in der Tat die rdfs:comment Tripel wegzulassen haben dann ...

+1

Da AKSW bereits eine ausgezeichnete Antwort geliefert hat, werde ich nur hinzufügen, dass 'MD5()' in der Tat eine Menge Übung im Vergleich ist zu dem anderen gemeinsamen Ansatz: ' BIND (URI (concat (" http://example.com/cocailailingrediants/ ", ENCODE_FOR_URI (str (? Ingredients_str)))) AS?Zutaten) BIND (URI (concat ("http://example.com/coctailrecipe/", ENCODE_FOR_URI (str (? rezept_str))) AS? Rezept) } 'was ist riskant. –

+0

Ah, vielen Dank, dass Sie mich wissen lassen, dass es andere nützliche Methoden wie 'ENCODE_FOR_URI' gibt - ich habe diese Methode nie benutzt, aber wahrscheinlich für lange Strings wäre das was Sie mit riskant meinen? – AKSW

+0

Vielen Dank! Es funktioniert alles jetzt :) –