이전 글에서 단어를 통해 결과를 조회할 수 있는 검색 쿼리를 작성해보았다.
▼▼▼ 검색 쿼리를 작성해놓은 이전 글 링크
그러나 단순 쿼리만으로는 검색에 아쉬운 점이 있었다.
1. 띄어쓰기
▶ 띄어쓰기 또한 문자로 인식하기 때문에 '가나'와 '가 나'를 검색했을 때 결과가 다르다
2. 순서
▶ 검색결과는 가장 일치하는 문자부터 출력되어야 한다
3. 검색 성능
▶ 글로벌 DBPedia에서 Execution timeout을 30000ms로 설정하고 검색하였을 경우 검색 시간이 많이 소모되는 것을 알 수 있다
물론 단어 포함 검색만 제공될 경우, 위의 쿼리만으로 충분하다.
하지만, RDF는 RDB와 달리 웹의 연결을 중심으로 두기 때문에, FORM 검색 보다는 검색엔진에서 검색하는 것처럼 구현해야하는 경우가 있다.
그렇다면 위의 3가지를 고려할 수 밖에 없다.
어떻게하면 구현할 수 있을까?
사실 아직 정상적인 방법은 찾지 못했다. SPARQL 쿼리 기능이 아직 부족하기 때문인지, 아니면 내가 잘 쓰지 못해서인지 확실하지 않지만, 나는 후자라고 생각한다.
그렇지만 인간은 언제나 해결방법을 찾아내기에 고민 끝에 잔꾀를 좀 부리기로 했다.
1. 띄어쓰기
띄어쓰기는 SQL처럼 %를 이용하면 된다.
필요에 맞게 %의 위치를 변경해주면 된다.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT *
WHERE{
?s rdfs:label ?o.
FILTER (?o LIKE "%가%나%")
}
LIMIT 20
2. 순서
순서는 꾀를 좀 부렸다. 가장 일치하는 결과를 먼저 보여주기 위해 UNION을 사용해서 조회한다.
1. 전부 일치하는 결과
2. Full Text가 포함된 결과
3. 모든 음절이 포함된 결과
의 순서로 결과를 조회한다.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT *
WHERE{
{
SELECT *
WHERE{
?s rdfs:label ?o.
FILTER(STR(?o) = "가나")
}
}
UNION
{
SELECT DISTINCT *
WHERE{
?s rdfs:label ?o.
?o bif:contains "'가나'".
}
}
UNION
{
SELECT DISTINCT *
WHERE{
?s rdfs:label ?o.
?o bif:contains "'가나*'".
}
}
UNION
{
SELECT DISTINCT *
WHERE{
?s rdfs:label ?o.
FILTER(?o LIKE "%가%나%").
}
}
}
이렇게 작성할 수 있다.
UNION 외에 DISTINCT와 bif:contains를 사용했는데 DISTINCT는 SQL과 동일하게 중복을 제외한 결과를 조회하고, bif:contains는 Full Text Search를 지원하는 기능이다. 아래에서 조금 더 살펴보겠다.
※ FILTER(STR(?o) = "가나") => STR로 전부 일치하는 내용 검색 시 Endpoint에 따라 조회가 안되는 경우가 있다. 그럴 때는 해당 쿼리를 다르게 변경해야 할 것 같다.
3. 검색 성능
이 부분이 어려웠다. CONTAINS나 UNION 등을 사용하니 검색 성능이 훨씬 떨어졌는데, 이를 보완할 수 있었던 것이 ' bif:contains '였다. bif:contains는 Full Text Search를 지원하는 기능이라고 하는데 아직 어떻게 돌아가는지 정확하게 파악하지 못했다.
그렇지만, CONTAINS, LIKE, REGEX 등을 사용하는 것보다 bif:contains로 조회를 하면 매우 빠르게 결과가 조회된다.
하지만, bif:contains를 사용할 때는 2가지 유의점이 있다.
(1) 한글 단어로 조회할 때 CONTAINS 등은 더블 쿼테이션("") 안에 단어를 그대로 적으면 되지만, bif:contains는 더블 쿼테이션("")안에 싱글 쿼테이션('')으로 한번 더 감싸주어야 한다.
SELECT *
WHERE{
?s rdfs:label ?o.
?o bif:contains "'가나'".
}
(2) bif:contains는 Full Text Search이기 때문에 음절이 따로 떨어져있으면 검색되지 않는다.
하지만 bif:contains는 "'가나*'"과 같이 * 기능을 제공한다.
예를 들어 '가나'로만 조회하면 '가나'가 띄어쓰기 등으로 따로 구분된 결과만 조회한다.
그러나 '가나*'로 조회하면 가나 뒤에 다른 글자가 붙어도 조회가 되므로 더 많은 조회가 가능하다.
🤞 도움이 되셨기를 바랍니다. 한 번의 클릭과 댓글은 어딘가의 누군가에게 진실로 큰 힘이 됩니다. 🐱🏍
'Web Development > SPARQL' 카테고리의 다른 글
[SPARQL / RDF] 속성 중 하나만 가지고 있어도 조회하기(feat. 외부조인 outer join) (0) | 2022.01.18 |
---|---|
[SPARQL / RDF] 동일한 URI의 여러 행 데이터를 한 행으로 조회(feat. 카티션 프로덕트/Cartesian Product) (0) | 2022.01.18 |
[SPARQL / RDF] 검색어(단어)가 포함된 결과 조회하기 (0) | 2022.01.17 |
[SPARQL / RDF] SPARQL 트리플 패턴을 간단하게 이해해보기 (0) | 2022.01.17 |
[SPARQL / RDF] LOD 데이터와 SPARQL을 RDB 개념으로 간단하게 이해해보기 (2) | 2022.01.14 |
댓글