2017-10-16 1 views
0

正しい形式を生成する正しいSPARQLクエリを作成するのに苦労しているので、Protegeを開くことができます。私たちのオントロジはカクテルに関するもので、材料(dbp:ingredients)とレシピ(dbp:prep)を含め、データベースにDBPediaのカクテルをすべて載せたいと考えています。データベースでカクテルを入手するのはうまくいくが、成分とレシピはうまくいかない。 ??私は今、次のクエリがあります。今宣言されていないSPARQLのクエリとしてのリテラルCONSTRUCTクエリ

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

を持つことになり、リテラルは被験者することはできません。オブジェクトプロパティではなくデータプロパティを宣言し、それぞれのリテラルに値を設定する必要があります。オブジェクトを抽出するためにこれらのリテラルを解析するのは難しいようです。おそらく、Wikidataにカクテルに関するより構造化された情報を問い合わせることができます(テキスト記述を保持したい場合は、DBpediaへの連合クエリを使用します)。 BTW:https://stackoverflow.com/a/44227937/7879193 –

+0

したがって、浮動小数点数としてリテラルを宣言することは不可能です: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) 
} 

レシピ(原料)がすでにリソースである場合は、どういうわけか失敗します。 DBpediaではdbp:prepdbp:ingredientsはDBpediaでは保持されませんが、確かにわからない場合は、実際にリソースとリテラルの両方を許可する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レシピ) } 'は危険です。 –

+0

ああ、ENCODE_FOR_URIのような他の便利なメソッドがあることを私に教えてくれてありがとう - 私はこのメソッドを使ったことはありませんが、おそらく長い文字列の場合、これはあなたが危険なことを意味するでしょうか? – AKSW

+0

ありがとうございます!それはすべて今働いている:) –