SPARQL TextSearch
提供:TogoWiki
SPARQLでテキスト検索をする方法の調査
SPARQL仕様ではFilter regexを使用してテキスト検索をすることになっているが、データ量が増えると全く使用できないレベルで遅くなる。
そのため、各トリプルストアは独自に全文検索の仕組みを提供していることがある。
独自機能であるため記述方法や挙動が異なるため調査する。
目次 |
SPARQL仕様
テキスト完全マッチであればオブジェクトにそのまま指定する。
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . <http://example.com/test> rdfs:label "GI:16329170" .
SELECT ?s ?p WHERE { ?s ?p "GI:16329170" .} ------------------------------ s p http://example.com/test http://www.w3.org/2000/01/rdf-schema#label
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<http://example.com/test> rdfs:label "Title"@en .
テキストの言語が指定してある場合には、言語タグまで指定しないとマッチしない。
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . <http://example.com/test> rdfs:label "Tokyo"@en .
SELECT ?s ?p WHERE { ?s ?p "Tokyo" . } ------------------------------ s p
SELECT ?s ?p WHERE { ?s ?p "Tokyo"@en . } ------------------------------ s p http://example.com/test http://www.w3.org/2000/01/rdf-schema#label
テキストのあいまい検索(部分一致)をする場合にはFilter regexを使用する。3番目の引数"i"は大文字小文字を区別しない。
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . <http://example.com/test> rdfs:label "Bacteria"@en .
SELECT ?text WHERE { ?s ?p ?text FILTER regex (?text, "bac", "i") . } ------------------------------ text "Bacteria"@en
単語の途中の文字列でもヒットする
SELECT ?text WHERE { ?s ?p ?text FILTER regex (?text, "cte", "i") . } ------------------------------ text "Bacteria"@en
Virtuoso
SPARQL文に加えて、フルテキスト検索機能としてVirtuoso独自のプレディケート"bif:contains"を使用する。
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"Synechocystis"' . } ----------------------------- text "Synechocystis sp. PCC 6803 chromosome, complete genome."
インデックス生成のタイミング
フルテキスト検索用インデックスは、データのロードが終了した時点で自動的に開始され、データ追加等でも自動的に更新もされる(Virtuoso7.0からか?)
そのため、ロード直後でインデックスの生成が終わらない間は、bif:containsで検索してもヒットしない(100億トリプルでロード終了からインデックス生成に3時間掛った)。
※GUIからアップロードした場合には自動でインデックス作成されないかもしれないので、アップロード後にisqlで次のコマンドを叩く。
VT_INC_INDEX_DB_DBA_RDF_OBJ();
AND検索
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"Synechocystis" AND "PCC"' . } ----------------------------- text "Synechocystis sp. PCC 6803 chromosome, complete genome."
OR検索
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"Synechocystis" OR "hoge"' . } ----------------------------- text "Synechocystis sp. PCC 6803 chromosome, complete genome."
単語単位の検索になる
- 単語単位に分解されインデックスが生成されるので(形態素解析)、単語の途中の文字列を指定してもヒットしない。
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"Synech"' . } ----------------------------- text (ヒット無し)
ワイルドカード「*」は使えるが。。。
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"chro*"' . } ----------------------------- text "Synechocystis sp. PCC 6803 chromosome, complete genome."
ワイルドカード「*」は形態素解析で区切られた単語のうち頭4文字は指定されなければならない。
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"chr*"' . } ----------------------------- エラー:Virtuoso 22023 Error FT370: Wildcard word needs at least 4 leading characters
どういうものが単語の区切りになるかは資料がない。
空白、".", ",", ":" 等で区切られる様子だが、それ以外の記号もあるはず。
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . <http://example.com/test> rdfs:label "GI:16329170" .
"GI:16329170"は":"が区切り文字になり、"GI"と"16329170"に分かれる(と思われる)。
その上で頭4文字以上の指定が必要なので、"16329170"の頭4文字以上指定しなければエラー
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"GI:163*"' . } ----------------------------- エラー:Virtuoso 22023 Error FT370: Wildcard word needs at least 4 leading characters
SELECT ?text WHERE { ?s rdfs:label ?text . ?text bif:contains '"GI:1632*"' . } ----------------------------- text "GI:16329170"
Jena
Jena 2.11.0から新たにテキスト検索用のモジュールがリリースされ、SPARQLに独自のプレディケートを指定する。
(動作未確認)
PREFIX text: <http://jena.apache.org/text#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?s { ?s text:query (rdfs:label 'word' 10) ; rdfs:label ?label }
Text searches with SPARQL
検索インデックス生成にはApache LuceneかApache Solrを使用できる様子。
Jena 2.11.0以前はLARQというテキスト検索機能が用意されていた。
同じくApache Solrと連携しており、独自のプレディケートを記述する形式だが、互換性はなくなった。
LARQ形式(?)
PREFIX pf: <http://jena.hpl.hp.com/ARQ/property#> SELECT ?doc { ?lit pf:textMatch '+text' . ?doc ?p ?lit }
Stardog
LARQ()と同等の記述で全文検索をサポートしている様子。 (動作未確認) http://docs.stardog.com/java/ (リンク切れ)
- 最新の仕様は以下のページに [yayamamo追記 2017/2/24]