데이터로 다시 읽는 조선시대 양반의 생활

지암일기 LOD:

지암일기 링크드 오픈 데이터 접속 및 활용


지암일기 데이터베이스는 기본적으로 시맨틱 웹 환경을 고려한 시맨틱 데이터베이스 형식으로 편찬되었습니다. 시맨틱 웹 환경을 고려하였다는 것은 곧 시맨틱 웹 아키텍쳐의 여러 요소를 데이터베이스 형식에 반영하였음을 의미합니다. XML로 기초 텍스트 데이터베이스를 구축하고 OWL 기반에서 온톨로지를 설계하고 RDF 형식의 데이터베이스를 구축한 것은 모두 그러한 맥락의 연장선상에서 시도한 것입니다. 지암일기 LOD는 데이터베이스 구축 과정에서 정리한 RDF 데이터를 토대로 구축한 결과물입니다. SPARQL Endpoint를 통해서 쉽고 빠르게 링크드 데이터에 접근할 수 있습니다.

SPARQL(SPARQL Protocol and RDF Query Language)은 Linked Data를 질의하는 데 사용되는 언어로, W3C(World Wide Web Consortium)에 의해 표준으로 지정되었습니다. Linked Data를 자유롭게 조작하기 위해서는 SPARQL 문법을 익혀야 합니다. 다음의 링크는 SPARQL 문법을 익히는 데 도움이 될 것입니다.

* SPARQL Query Language for RDF (W3C)

* 국가서지 LOD의 About SPARQL (국립중앙도서관)

* 한국관광공사 LOD의 SPARQL 사용예

SPARQL을 이용하여 데이터를 탐색하기 위해서는 SPARQL 문법 뿐만 아니라, 탐색하고자 하는 데이터의 체계, 즉 온톨로지(Onotlogy)도 알아야 합니다. 지암일기의 온톨로지는 다음의 페이지에서 확인할 수 있습니다.

* 지암일기 온톨로지

주소

http://lod.jiamdiary.info/jiamdiary/sparql

파라미터

* query: URL 인코딩된 SPARQL 질의문

* foramt: 응답(Response) 유형 - xml, json, csv, tsv

예시
http://lod.jiamdiary.info/jiamdiary/sparql?query=SELECT ?s ?p ?o WHERE {?s ?p ?o} limit 2&format=json
{
"head": {
	"vars": [ "s" , "p" , "o" ]
} ,
"results": {
	"bindings": [
		{
			"s": { "type": "uri" , "value": "http://dh.aks.ac.kr/ontology/jad#N1692072603" } ,
			"p": { "type": "uri" , "value": "http://dh.aks.ac.kr/ontology/jad#name" } ,
			"o": { "type": "literal" , "value": "1692년7월26일내용3" }
		} ,
		{
			"s": { "type": "uri" , "value": "http://dh.aks.ac.kr/ontology/jad#N1692072603" } ,
			"p": { "type": "uri" , "value": "http://dh.aks.ac.kr/ontology/jad#uri" } ,
			"o": { "type": "literal" , "value": "http://jiamdiary.info/iri/jad#N1692072603" }
		}
	]
}
}

다음은 지암일기의 데이터를 탐색할 때 자주 사용되는 질의 패턴을 SPARQL 질의문의 형식으로 표현한 것입니다. 질의문 박스에 마우스를 올리면 우측 상단에 'COPY' 버튼이 생깁니다. 질의문을 복사해서 질의 창에 붙여 넣은 뒤 결과를 확인해보세요.

지암일기에 등장하는 인물들의 목록 불러오기
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX jad: <http://dh.aks.ac.kr/ontology/jad#>
PREFIX ekc: <http://dh.aks.ac.kr/ontology/ekc#>

select ?person ?p_name	#where 이하의 조건을 만족하는 변수 ?person, ?p_name 보이기
where{
	?entry ekc:mentions ?person .	#변수 ?entry는 변수 ?person을 언급(ekc:mentions)한다.
	?entry rdf:type jad:Entry .	#변수 ?entry의 클래스(rdf:type)는 jad:Entry이다.
	?person rdf:type jad:Person .	#변수 ?person의 클래스(rdf:type)는 jad:Person이다.
	?person jad:name ?p_name .	#변수 ?person의 이름(jad:name) 속성은 변수 ?p_name이다.
} limit 30	#전체 결과 중 30개만 보이기
지암일기에 등장하는 인물들의 목록 뿐만 아니라, 인물이 등장하는 일기의 정보까지 확인하고 싶을 때
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX jad: <http://dh.aks.ac.kr/ontology/jad#>
PREFIX ekc: <http://dh.aks.ac.kr/ontology/ekc#>

select ?person ?p_name ?diary ?d_name ?url	#where 이하의 조건을 만족하는 변수 ?person, ?p_name, ?diary, ?d_name, ?url 보이기
where{
	?entry ekc:mentions ?person .	#변수 ?entry는 변수 ?person을 언급(ekc:mentions)한다.
	?entry rdf:type jad:Entry .	#변수 ?entry의 클래스(rdf:type)는 jad:Entry이다.
	?person rdf:type jad:Person .	#변수 ?person의 클래스(rdf:type)는 jad:Person이다.
	?person jad:name ?p_name .	#변수 ?person의 이름(jad:name) 속성은 변수 ?p_name이다.

	?entry jad:isElementOf ?diary .	#변수 ?entry는 변수 ?diary의 구성요소(jad:isElementOf)이다.
	?diary jad:name ?d_name .	#변수 ?diary의 이름(jad:name) 속성은 변수 ?d_name이다.
	?diary jad:url ?url	#변수 ?diary의 원문 웹페이지(jad:url) 속성은 변수 ?url이다.
} order by ?person	#전체 결과를 변수 ?person 기준으로 정렬하기
limit 30	#전체 결과 중 30개만 보이기
해남윤씨 인물들의 목록 불러오기(문자열 조건 검색)
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX jad: <http://dh.aks.ac.kr/ontology/jad#>

select ?person ?clan	#where 이하의 조건을 만족하는 변수 ?person, ?clan 보이기
where{
	?person jad:clan ?clan .	#변수 ?person의 성씨(jad:clan) 속성은 변수 ?clan이다.
	filter regex(?clan, "^해남윤").	#변수 ?clan의 문자열은 '해남윤'으로 시작(^)한다. 문자열 정규식 검색: regex(문자열,패턴). ^: 문자열 시작 기호
} limit 30	#전체 결과 중 30개만 보이기 
지암일기에 등장하는 장소 중에 사찰로 추정되는 장소 불러오기(문자열 조건 검색)
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX jad: <http://dh.aks.ac.kr/ontology/jad#>
PREFIX ekc: <http://dh.aks.ac.kr/ontology/ekc#>

select ?place ?chinname ?latitude ?longitude ?url	#where 이하의 조건을 만족하는 변수 ?place, ?chinname, ?latitude, ?longitude, ?url 보이기
where{
	?entry ekc:mentions ?place .	#변수 ?entry는 변수 ?place를 언급(ekc:mentions)한다.
	
	?entry jad:isElementOf ?diary .	#변수 ?entry는 변수 ?diary의 구성요소(jad:isElementOf)이다.
	?diary jad:url ?url .	#변수 ?diary의 원문 웹페이지(jad:url) 속성은 변수 ?url이다.

	?place rdf:type jad:Place .	#변수 ?place의 클래스(rdf:type)는 jad:Place 이다.
	?place jad:chinname ?chinname .	#변수 ?place의 한자명(jad:chinname) 속성은 변수 ?chinname 이다.
		filter (regex(?chinname, "寺$") || regex(?chinname, "巖$")).	#변수 ?chinname의 문자열은 '寺'로 끝($)나거나 '巖'로 끝($)난다. $: 문자열 끝 기호. ||: 또는(or) 기호
	?place jad:latitude ?latitude .	#변수 ?place의 위도(jad:latitude) 속성은 변수 ?latitude 이다.
	?place jad:longitude ?longitude .	#변수 ?place의 경도(jad:longitude) 속성은 변수 ?longitude 이다.

} limit 30	#전체 결과 중 30개만 보이기
윤이후와 관련있는 인물들 불러오기(데이터 간의 관계를 탐색할 때)
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX jad: <http://dh.aks.ac.kr/ontology/jad#>

select ?jiam ?rel ?someone ?s_name	#where 이하의 조건을 만족하는 변수 ?jiam, ?rel, ?someone, ?s_name 보이기
where{
	?jiam jad:korname "윤이후" .	#변수 ?jiam의 한글명(jad:korname) 속성은 "윤이후" 이다.
	?jiam ?rel ?someone .	#변수 ?jiam은 변수 ?someone과 변수 ?rel 의 관계이다. 
	?someone rdf:type jad:Person .	#변수 ?someone의 클래스(rdf:type)는 인물(jad:Person) 이다.
	?someone jad:korname ?s_name .	#변수 ?someone의 한글명(jad:korname) 속성은 변수 ?s_name 이다.
} limit 30	#전체 결과 중 30개만 보이기
생활 유형 중 '수신'과 '송신'에 해당되는 일기 내용의 개수 확인하기
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX jad: <http://dh.aks.ac.kr/ontology/jad#>
PREFIX edm: <http://www.europeana.eu/schemas/edm#>

select ?lifestyle ?l_name (count(?entry) as ?entry_count)	#where 이하의 조건을 만족하는 변수 ?lifestyle, ?l_name 보이기. 변수 ?entry는 group by의 기준에 따라 개수(count)를 세서 변수 ?entry_count 의 이름으로 보이기.
where{
	?entry edm:isRelatedTo ?lifestyle . #변수 ?entry는 변수 ?lifestyle과 관련(edm:isRelatedTo)이 있다.
	?entry rdf:type jad:Entry . #변수 ?entry의 클래스(rdf:type)는 내용(jad:Entry) 이다.
	?lifestyle rdf:type jad:Lifestyle . #변수 ?lifestyle의 클래스(rdf:type)는 생활(jad:Lifestyle) 이다.
	?lifestyle jad:name ?l_name . #변수 ?lifestyle의 이름(jad:name) 속성은 변수 ?l_name 이다.
} group by ?lifestyle ?l_name	#변수 ?lifestyle과 ?l_name 기준으로 결과를 그룹화
order by desc(?entry_count)	#전체 결과를 변수 ?entry_count 기준으로 내림차순(desc) 정렬