2017-10-16 109 views
0

我很努力地創建一個正確的SPARQL查詢,它將生成正確的格式,以便我可以在其中打開Protege。我們的本體論是關於雞尾酒的,我們希望在我們的數據庫中包含所有DBPedia雞尾酒,包括配料(dbp:ingredients)和配方(dbp:prep)。在數據庫中獲得雞尾酒的效果很好,但其成分和配方不是。現在我有以下查詢:??作爲SPARQL構造中的主題字面值查詢

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.} 

由於原料和配方,現在沒有宣佈,它不會在門徒的個人標籤顯示。但是,當我加入這個到查詢的構造物部分:

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

我得到一個錯誤:

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

我想是因爲準備和DBpedia的成分只是一個字符串,沒有任何鏈接的數據。 但是,如何使這項工作在Protege中顯示?

+1

總之,文字不能科目。您應該聲明數據屬性 - 而不是對象屬性 - 並使相應的文字成爲它們的值。爲了提取對象,似乎很難解析這些文字。也許你可以查詢維基數據獲取更多關於雞尾酒的結構化信息(如果你想保留文本描述,可以使用DBpedia的聯合查詢)。順便說一句:https://stackoverflow.com/a/44227937/7879193 –

+0

因此,不可能將Literal聲明爲owl:NamedIndividual?或者,也許有任何方法來轉換查詢中的文字,以便這是可能的? –

+0

IRI被用作'owl:NamedIndividual'的唯一標識符。 – AKSW

回答

1

無法將字面值作爲RDF三元組的主題。相反,創建配方和配料資源+將字符串值附加爲rdfs:comment(或者可能是rdfs:label)可能是一種解決方法。它的工作原理是這樣的:

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

注意,它會以某種方式如果配方(RESP成分)已經是一個資源失敗。它不適用於DBpedia上的dbp:prepdbp:ingredients,但一般來說,如果您不確定,並且您有一些實際上允許資源和文字的rdf:Property,則需要正確處理此問題。通過使用IF-ELSE結構:

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) 

,你也必須省略rdfs:comment三倍那麼確實...

+1

由於AKSW已經提供了一個很好的答案,我只是補充說'MD5()到另一種常見方法:' BIND(URI(concat(「http://example.com/coctailingrediants/」,ENCODE_FOR_URI(str(?ingredients_str))))AS?成分) BIND(URI(concat(「http://example.com/coctailrecipe/」,ENCODE_FOR_URI(str(?recipe_str))))AS?recipe) }'這是有風險的。 –

+0

啊,謝謝你讓我知道還有其他有用的方法,比如'ENCODE_FOR_URI' - 我從來沒有使用過這種方法,但是對於長字符串,這可能就是你冒險的意思嗎? – AKSW

+0

非常感謝!它現在都在工作:) –