본문 바로가기
Web Development/SPARQL

[SPARQL / RDF] 검색어(단어)가 포함된 결과 조회하기

by 감자맹고우 2022. 1. 17.
728x90
반응형

SPARQL / SPARQL 예제로 프로젝트를 진행하다가 검색 기능을 구현하게 됐다.

RDB였다면 %나 CONCAT을 이용하면 됐지만, SPARQL에서 해당 쿼리를 작성하려고 하니 쉬워보이지 않았다.

 

하지만, 역시 SPARQL도 쿼리의 일종이기 때문에 관련 기능을 제공하고 있었다.

바로 FILTER를 이용한 방법이다.

 

SPARQL의 FILTER는 SQL의 WHERE와 유사한 기능을 한다.

이 FILTER를 이용해서 조회할 결과의 조건을 설정할 수 있다.

FILTER는 또한, 다양한 함수와 기능을 제공하는데 아래 w3c의 공식 링크에서 자세한 내용을 찾아볼 수 있다.

 

 

SPARQL Query Language for RDF

 

www.w3.org

 

 

반응형

 

 

[검색 기능 구현]

 

그 중에서 검색을 위해 사용할 수 있는 기능은 다음 4가지가 있다.

 

1. LIKE
2. STR

2. REGEX
3. CONTAINS

 

이번에는 데이터가 많은 DBPedia의 Endpoint를 사용해보겠다. 빠른 조회를 위해 한국 DB Pedia에서 진행한다.

글로벌 DBPedia와 한국 DBPedia의 데이터양이 다르니 유의한다.

 

 

Virtuoso SPARQL Query Editor

 

143.248.135.47

 

 

DBPedia의 Endpoint에서 다음과 같이 쿼리를 작성해보자.

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT *
WHERE{
    ?s rdfs:label ?o.
}
LIMIT 5

 

결과로 아래와 같이 rdfs:label 속성이 있는 URI와 속성값이 5개 출력되었다.

s o
http://www.w3.org/2002/07/owl#Thing "Thing"
http://www.w3.org/2002/07/owl#Class "Class"
http://www.w3.org/2002/07/owl#Nothing "Nothing"
http://www.w3.org/2002/07/owl#complementOf "complementOf"
http://www.w3.org/2002/07/owl#unionOf "unionOf"

 

반응형

 

여기서 '가' 라는 단어가 rdfs:label 속성에 포함된 결과만 출력하고 싶다면 어떻게 하면 될까?

 

1. LIKE

 

기존 SQL과 가장 유사한 방법이다.

%와 LIKE를 통해서 포함된 문자를 검색할 수 있다.

 

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT * WHERE{
    ?s rdfs:label ?o.
    FILTER (?o LIKE "%가%")
}
LIMIT 5

 

검색 결과는 아래의 REGEX나 CONTAINS 와 동일하다.

아쉽게도 필자는 이 방법을 가장 늦게 알게 되었다.

 

 

2. STR

 

STR은 다음과 같이 사용한다.

 

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT *
WHERE{
    ?s rdfs:label ?o.
    FILTER(STR(?o) = "가")
}
LIMIT 5

 

FILTER는 아래와 같이 WHERE 절 안에 작성한다.

FILTER의 위치는 FILTER에 사용되는 변수가 트리플로 작성된 후에 위치해야 함을 유의한다.

 

결과는 아래와 같다.

s o
http://ko.dbpedia.org/resource/가 "가"@ko

즉, STR로 쿼리를 작성했을 때는, 정확히 일치하는 값만 출력된다.

 

 

3. REGEX

 

이를 해결하기 위해, REGEX를 사용해보겠다.

우선, STR을 사용해 문자열로 치환하고 REGEX를 사용한다.

 

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT *
WHERE{
    ?s rdfs:label ?o.
    FILTER REGEX(STR(?o), "가")
}
LIMIT 5

 

결과는 다음과 같다.

s o
http://ko.dbpedia.org/resource/1848년_헝가리_혁명 "1848년 헝가리 혁명"@ko
http://ko.dbpedia.org/resource/1904년_하계_올림픽_헝가리_선수단 "1904년 하계 올림픽 헝가리 선수단"@ko
http://ko.dbpedia.org/resource/1906년_중간_올림픽_헝가리_선수단 "1906년 중간 올림픽 헝가리 선수단"@ko
http://ko.dbpedia.org/resource/1908년_하계_올림픽_헝가리_선수단 "1908년 하계 올림픽 헝가리 선수단"@ko
http://ko.dbpedia.org/resource/1917년_국가_지도자_목록 "1917년 국가 지도자 목록"@ko

 

즉, REGEX를 사용했을 경우에는 "가" 라는 단어가 포함된 결과를 모두 출력한다.

 

반응형

 

4. CONTAINS

 

CONTAINS는 다음과 같이 쿼리를 작성하면 된다.

 

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT *
WHERE{
    ?s rdfs:label ?o.
    FILTER CONTAINS (?o, "가")
}
LIMIT 5

 

결과는 REGEX를 사용한 2번과 동일하다.

 

 

그러나, 실제 개발을 진행하다보면 REGEX와 CONTAINS만으로 검색기능을 구현하기에는 아쉬운 점이 있다.

 

 

 

[아쉬운 점]

1. 띄어쓰기 (띄어쓰기 또한 문자로 인식하기 때문에 '가나'와 '가 나'를 검색했을 때 결과가 다르다)
2. 순서 (검색결과는 가장 일치하는 문자부터 출력되어야 한다)
3. 검색 성능 (글로벌 DBPedia에서 Execution timeout을 30000ms로 설정하고 검색하였을 경우 검색 시간이 많이 소모되는 것을 알 수 있다)

 

그렇기에, 이어서 해당 문제점을 다소 개선할 수 있는 방법을 공유하고자 한다.

 

🤞 도움이 되셨기를 바랍니다. 한 번의 클릭과 댓글은 어딘가의 누군가에게 진실로 큰 힘이 됩니다. 🐱‍🏍

 

728x90
반응형

댓글