2017-10-16 12 views
0

올바른 형식을 생성하여 올바른 Protege를 열 수있는 올바른 SPARQL 쿼리를 만드는 데 어려움을 겪고 있습니다. 우리의 온톨로지는 칵테일에 관한 것입니다. 재료 (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.} 

이후 재료와 조리법을, 그것은 Protege는의 개인 탭에 표시되지 않습니다. 내가 쿼리의 구조물 부분이 추가 때 :

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

를 오류가 발생합니다 다음 준비 및 dbpedia에 재료 그냥 문자열, 아니 링크 된 데이터 때문에

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

나는 생각한다. 그러나 Protege에 표시되도록하려면 어떻게해야합니까?

+1

있을 것입니다, 리터럴 대상이 될 수 없습니다. 객체 속성이 아닌 데이터 속성을 선언하고 각각의 리터럴을 값으로 설정해야합니다. 객체를 추출하기 위해 이러한 리터럴을 구문 분석하는 것이 어려워 보입니다. 아마도 Wikidata에 쿼리하여 칵테일에 대한보다 구조화 된 정보를 얻을 수 있습니다 (텍스트 설명을 유지하려면 DBpedia에 연합 쿼리 사용). BTW : https://stackoverflow.com/a/44227937/7879193 –

+0

따라서 Literal을 올빼미로 선언하는 것은 불가능합니다. NamedIndividual? 또는 쿼리에서 리터럴을 변환 할 수있는 방법이 있습니까? –

+0

IRI는 'owl : NamedIndividual'의 고유 식별자로 사용됩니다. – AKSW

답변

1

리터럴을 RDF 트리플의 주제로 사용할 수 없습니다. 대신, 조리법 및 재료 + rdfs:comment (또는 아마도 rdfs:label)으로 문자열 값을 첨부하는 리소스를 만들면 문제를 해결할 수 있습니다. 그것은 다음과 같이 작동 레시피 (. RESP 성분)가 이미 자원의 경우

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에 대해서는 보유하지 않지만 일반적으로 확실하지 않은 경우 실제로 리소스와 리터럴을 모두 허용하는 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 ("concat ("http://example.com/coctailrecipe/ ", ENCODE_FOR_URI (str (? recipe_str)))) 조리법) }'위험합니다. –

+0

아, 감사합니다. ENCODE_FOR_URI와 같은 유용한 메소드가 있다는 것을 알려 줘서 고마워요.이 방법을 사용하지는 않았지만, 긴 문자열일지도 모르지만, 이것은 위험하다는 것을 의미할까요? – AKSW

+0

대단히 감사합니다! 그것은 모두 지금 일하고있다 :) –