私は短い弦の大きなセットを持っています。部分文字列を含むアイテムのリストをフィルタリングするためのアルゴリズムとインデックス作成戦略は何ですか? たとえば、次のリストがあるとします。
val words = List(
"pick",
"prepick",
"picks",
"picking",
"kingly"
...
)
部分文字列 "king" を含む文字列を見つけるにはどうすればよいですか? 次のように問題をブルートフォースすることができます:
words.filter(_.indexOf("king") != -1) // yields List("picking", "kingly")
これは小さなセットの場合にのみ実用的です。現在、1,000 万の文字列をサポートする必要があり、将来の目標は数十億です。明らかに、インデックスを作成する必要があります。どんな指標?
MySQL に格納されている ngram インデックスの使用を検討しましたが、これが最善のアプローチかどうかはわかりません。検索文字列が ngram サイズよりも長い場合に、インデックスを最適にクエリする方法がわかりません。
Lucene の使用も検討しましたが、これは部分文字列の一致ではなく、トークンの一致を中心に最適化されており、単純な部分文字列の一致の要件をサポートしていないようです。Lucene には ngrams に関連するクラスがいくつかあります (org.apache.lucene.analysis.ngram.NGramTokenFilter
は一例です) が、これらは部分文字列の一致ではなく、スペル チェックとオートコンプリートのユース ケースを対象としているようで、ドキュメントは薄いです。
他にどのようなアルゴリズムとインデックス作成戦略を検討する必要がありますか? これをサポートするオープン ソース ライブラリはありますか? SQL または Lucene 戦略 (上記) を機能させることはできますか?
要件を説明する別の方法は、SQL を使用したものです。
SELECT word FROM words WHERE word LIKE CONCAT('%', ?, '%');
はユーザー?
が指定した検索文字列で、結果は検索文字列を含む単語のリストです。