ケースを無視しながら文字列リテラルと効率的に一致するSPARQLクエリを書き込む方法
質問
RDFSラベルに基づく概念に基づく概念に関連するタイプを見つけるために、JENA TDBから読み込まれている大きなオントロジーに対するSPARQLクエリを書き込むためにJENA ARQを使用しています。
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> "aspirin" .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}
.
これはかなりよく機能し、実際にはかなり迅速です(<1秒)。残念ながら、いくつかの用語では、私は大文字と小文字を区別しない方法でこのクエリを実行する必要があります。たとえば、Label "Tylenol"
はオントロジーにあるが、"tylenol"
ではなく、次のクエリが空になります。
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> "tylenol" .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}
.
フィルタ構文を使用してこのクエリの大文字と小文字を区別しないようにすることができます。
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
FILTER ( regex (str(?term), "tylenol", "i") )
}
.
しかし今クエリは完了するまでに1分以上かかります!より効率的な方法で大文字と小文字を区別しないクエリを書き込む方法はありますか?
解決
フィルタクエリの実行が遅くなる理由は、regentが解消されないため、PSOまたはPOSインデックスをスキャンしてRDFS:Label Predicateを使用してすべてのステートメントを見つけて、それらを正規表現に対してフィルタリングする必要があるためです。それが具体的なリソースにバインドされたとき(最初の例で)、OPSまたはPOSインデックスを使用して、RDFS:Label Predicateと指定されたオブジェクトリソースを使用して順序のみをスキャンできます。
このタイプのテキスト検索問題に対する一般的な解決策は、外部テキストインデックスを使用することです。この場合、JENAは、
他のヒント
SPARQLで使用できるすべての文字列演算子から、regex
はおそらく最も高価なものです。regex
を避けて、代わりにテストの両側にUCASE
またはLCASE
を使用している場合、クエリが速く実行される可能性があります。のようなもの
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
FILTER (lcase(str(?term)) = "tylenol")
}
.
これは速いかもしれませんが、一般的に、トリプルストアでのテキスト検索のための素晴らしいパフォーマンスを期待しないでください。トリプルストアはグラフマッチングが非常に優れており、文字列マッチングではそれほど良くない。