스파클 사용하기 SPARQL Tutorial - Optional Information

     




SPARQL Tutorial - Optional Information


RDF는 semi-structured 데이터라서 스파클의 질의기능으로 값이 없는 부분을 검색했을때 공백으로 나오게 하는 기능을 설명하는 것 같습니다. 


vc-db-2.rdf파일에 나이가 추가되었다고 했는데 4명중에 2명만 age 속성이 추가되었고 나머지 2명은 age속성이 없습니다. 이때 쿼리문으로 전체 사람의 정보를 불러온다면 어떻게 될까요?


PREFIX info:    <http://somewhere/peopleInfo#>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name ?age
WHERE
{
    ?person vcard:FN  ?name .
    OPTIONAL { ?person info:age ?age }
}


위와 같은 쿼리를 실행합니다 .


q-opt1.rq


찾는 값은 ?name과 ?age입니다. 조건절을 보면 name은 FN의 오브젝트값을 가리키고 age의 경우 나이를 가리킵니다. 나이를 표기하는 트리플에 괄호와 함께 OPTIONAL이라는 명령어가 있습니다. 

위 쿼리문을 실행하면 다음과 같은 결과가 나옵니다.




age속성값을 가지고있는 스미스 가족은 나이가 표기되었지만 없는 존 가족은 나이가 표기되지 않았습니다. 이번엔 OPTIONAL을 지우고 실행해 보도록 하겠습니다.


PREFIX info:   <http://somewhere/peopleInfo#>
PREFIX vcard:  <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name ?age
WHERE
{
    ?person vcard:FN  ?name .
    ?person info:age ?age .
}


q-opt2.rq


다음과 같은 결과를 볼 수 있습니다.


-----------------------
| name          | age |
=======================
| "Becky Smith" | 23  |
| "John Smith"  | 25  |
-----------------------



OPTIONALs with FILTERs


선택적인 옵션과 필터옵션을 동시에 사용하는 방법입니다. OPTIONAL기능은 어떤 스파클 연산자와 함께 사용할 수 있습니다. 다음 쿼리를 살펴봅시다.


PREFIX info:        <http://somewhere/peopleInfo#>
PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name ?age
WHERE
{
    ?person vcard:FN  ?name .
    OPTIONAL { ?person info:age ?age . FILTER ( ?age > 24 ) }
}


q-opt3.rq


OPTIONAL이 두가지 문장을 포함하고 있습니다. 하나는 ?person info:age ?age 이고 하나는 FILTER문 입니다. 이 경우에는 age가 24이상일 경우에만 age가 출력이 됩니다. 즉 24살 이하는 나이가 출력이 안되고 공백으로 나오게 됩니다.


-----------------------
| name          | age |
=======================
| "Becky Smith" |     |
| "Sarah Jones" |     |
| "John Smith"  | 25  |
| "Matt Jones"  |     |
-----------------------


위와 같이, Becky Smith의 나이는 "23"이라는 값을 가지고 있지만 "24"보다 낮아서 출력이 되지 않습니다. 


PREFIX info:        <http://somewhere/peopleInfo#>
PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name ?age
WHERE
{
    ?person vcard:FN  ?name .
    OPTIONAL { ?person info:age ?age . }
    FILTER ( !bound(?age) || ?age > 24 )
}


q-opt4.rq


이번 쿼리는 이전 쿼리와 조금 다릅니다. OPTIONAL이 하나의 트리플에만 적용되고 FILTER문은 OPTIONAL 밖에 위치합니다. FILTER에서는 age값이 없거나 age값이 24가 넘는 값을 표시한다고 적혀있습니다. (bound라는 값은 값이 있는지 없는지 확인하는 함수이고 앞에 !가 있기때문에 없을때 참이 되는 문장입니다. )


쿼리문을 해석해보면 "풀네임과 나이를 출력하는데 나이는 있으나 없으나 상관없고, 나이가 없거나 있다면 24살 위인사람만 출력"이라는 뜻입니다.


-----------------------

| name          | age |
=======================
| "Sarah Jones" |     |
| "John Smith"  | 25  |
| "Matt Jones"  |     |
-----------------------


결과는 위와 같습니다.


OPTIONALs and Order Dependent Queries


마지막으로 OPTIONAL 연산자의 주의사항에 대해 말해줍니다. OPTIONAL 연산자를 여러 번 사용할 경우, 맨 첫 번째 OPTIONAL연산자에 해당하는 값만 두 번째 OPTIONAL연산자로 들어갑니다. 즉 첫 번째에서 해당 안 되는 경우라면 두 번째에는 아예 비교도 안 한다는 뜻입니다.


PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name
WHERE
{
  ?x a foaf:Person .
  OPTIONAL { ?x foaf:name ?name }
  OPTIONAL { ?x vCard:FN  ?name }
}


위 코드에서 첫 번째 ?x foaf:name ?name 에 적용이 안되는 ?x는 두 번째 ?x vCard:FN ?name 에는 계산조차 하지 않고 그냥 무시됩니다. 왜냐면 이미 첫 번째 옵션에서 탈락한 값이니까요 ^^







여기까지 OPTIONAL에 대한 포스팅을 마치고, 다음은 union queries 챕터를 포스팅하겠습니다.

반응형

댓글

Designed by JB FACTORY