H:::SPARQL

H_16. VALUES 키워드

joyHong 2019. 12. 9. 12:27

SPARQL을 사용하다보면

질의한 결과에 대해 필터링을 해야할 때가 종종 있다.

그럴 경우에 사용할 수 있는 키워드가 VALUES 라는 것이다.

이는 SPARQL 1.1에서 제공한다.

 

우선 사용 법을 보면

SPARQL을 질의할 때 임의로 데이터셋을 만들어 두고 사용할 수 있다.

SELECT ?text 
WHERE {
  VALUES ?data { "사과" "무" "양파" }
  BIND(concat("나는 ", ?data, "라고 합니다.") as ?text)
}

변수에 들어가는 데이터는 { } 안에 있는 데이터로 바인딩 된다.

VALUES 라는 키워드 뒤에 변수명을 적고 { } 안에 데이터셋을 입력하면

위의 SPARQL을 실행하면 결과는 아래와 같다.

결과:

 

위의 예시는 1차원 데이테셋이고

2차원, 3차원 데이터셋을 만들 수 있다. 

이 때에는 변수명을 ( ) 안에 나열하게 되고 

데이테셋 역시 { } 안에 각각 ( ) 안에 나열하면 된다.

SELECT ?text 
WHERE {
   VALUES (?data  ?how)
   { 
      ("사과" "빨간")
      ( "무" "하얀")
      ( "바나나" "노란" )
   }
   BIND(concat("나는 ", ?how, " ", ?data, "라고 합니다.") as ?text)
}

결과:

여기까지는 기본적인 내용이고

이를 실제 데이터로 적용하려면 WHERE절에 매칭되는 결과 중

VALUES 키워드를 사용하여 필터링하여 원하는 결과만을 가져오도록 만들 수 있다.

아래의 파일은 아래서 설명하는 SPARQL에서 질의를 하기 위해 샘플로 사용는 예제이며, https://joyhong.tistory.com/85에서 설명한 과정에서 나온 결과이기도 하다.

example.ttl
0.00MB

첫번째로 생년으로 필터링을 해보기 위해 2000년 생인 학생을 찾아보는 질의문이다.

SELECT * 
WHERE {
   ?s a :Student .
   ?s :birthYear ?year.
   ?s :liveIn ?live.
   VALUES ?year  {
      2000
   }
}

결과:

여기에 1995년 생인 학생도 같이 찾으려면 { } 안에 값을 넣어주면 된다.

SELECT * 
WHERE {
   ?s a :Student .
   ?s :birthYear ?year.
   ?s :liveIn ?live.
   VALUES ?year  {
      2000 1995
   }
}

결과:

 

그 다음에는 2000년 생이거나 사는 곳이 제주인 학생도 찾아보는 질의문이다.

SELECT * 
WHERE {
   ?s a :Student .
   ?s :birthYear ?year.
   ?s :liveIn ?live.
   VALUES (?year ?live) {
      (2000 UNDEF)
      (UNDEF :제주)
   }
}

결과:

위의 예시에서 UNDEF는 매칭할 대상을 지정하지 않는다는 의미이다. 마치 와일드카드 (*) 와 같은 의미라고 보면 된다.

 

위의 두 예제만 보면 IF나 BIND 혹은 다이렉트 매칭으로 해결할 수 있는데? 라고 생각할 수도 있지만

좀 더 복잡한 질의문을 구성해야할 때는 VALUES의 간결함이 새롭게 다가올 것이다.

 

이를 좀 더 응용하면 Database 쿼리문 중에 CASE WHEN 구문과 유사한 사용법으로도 사용할 수 있다.

 

VALUES 의 데이터셋에 데이터값으로 특정값이 매칭되었을 때 바인딩되는 값을 설정함으로 사용하면 된다.

SELECT ?s ?tag 
WHERE {
   ?s a :Student .
   ?s :major ?m.
   BIND(regex(?m,"공학") as ?flag)
   VALUES (?flag ?tag) {
      (true "공대생")
      (false "")
   }
}

결과:

위의 예시에서는 학생의 전공명에 "공학"이 들어가 있으면 true, 아니면 false 값을 ?flag에 바인딩 시켰고

?flag 값이 true 이면 "공대생"으로, false이면 "" 으로 바인딩 시킨 예제이다.

 

여러개의 조건을 넣기 위해 질의문을 약간 수정하면 아래와 같다.

SELECT * {
   ?s a :Student .
   ?s :major ?m.
   BIND(SUBSTR(?m, STRLEN(?m)-2, 2) as ?flag)
   VALUES (?flag ?text) {
      ("공학" "공대생")
      ("문학" "문대생")
      (UNDEF "")
   }
}

결과:

전공명을 끝에서 3번째부터 2자리를 짤라 ?flag에 바인딩시켰고 그 값이 공학이면 "공대생", 문학이면 "문대생", 그 외에는  "" 으로 바인딩 시킨 예시이다.

위의 질의문도 역시 IF, BIND 를 사용하여 생성할 수 있는데 VALUES를 사용함으로 보다 간결한 SPARQL을 생성할 수 있다.