[Senna-dev 338] Re: N-gramインデックス時の1byte文字の検索

Back to archive index

Tasuku SUENAGA a****@razil*****
2006年 9月 14日 (木) 23:43:00 JST


末永です。

ちょっと長文になっちゃいました。

> Senna の N-gram インデックスについて以下のような事例から、1byte のインデッ
> クスについては、分かち書きになっている??との疑問を持ちましたのでメール
> させていただきました。

SennaのN-gramは、いわゆるアルファベット、数字、記号については、
連続している同じ種類の文字は
1つの単語として切り出すようにしています。

さて、MySQL経由でSennaインデックスを作成する場合、
デフォルトで「NORMALIZE」という正規化を行うフラグが立ちます。

正規化とは、A->aやA->aのように
文字列をある単一の形に合わせる処理です。
この正規化の際に、個々の文字の文字種を判定しています。
正規化を行わない場合、文字種判定は行われません。

[Senna-dev 336]で島村さんが指摘されているとおり、
NO NORMALIZEを指定すると、
正規化処理によって行われる文字種判定が行われず、
すべてが同じ文字種と判定され、
したがって宮本さんが想定されるようなN-gramでの切り出しが行われます。
(これは、将来的には修正されるべきだと認識しています)

しかし、NO NORMALIZEを指定した場合には、
たとえば「Smap」で「SMAP」を検索することができません。

--

さて、N-gram時に「perl」という単語が
インデックスされているとしましょう。
Sennaでは、アルファベット・数字・記号からなる単語について、
前方一致検索しか対応しておりません。
それ以外の文字からなる単語は、
前方一致検索も後方一致検索も可能です。

よって、「per」では検索できますが、「erl」では検索できません。

理由としては、
英単語は語尾の変更はよくあるが、
語幹の変更が少ないためです。
インデックスサイズを減らし、
検索速度を向上し、
さらにノイズが少ない検索を実現するために、
ニーズが低いと考えられる単語については
インデックスしないようにしています。

--

ちなみに、今回の話題とは直接は関係ないですが、
デフォルトのクエリでは、
他に「per」という単語を含む文書がある場合、
「perl」を含んだ文書は結果に含まれません。

これは、完全一致する単語のみを結果に含めることによって、
精度の高い(適合率の高い)検索を実現するためです。

--

宮本さんがどのような用途にSennaを利用されるかにもよるのですが、
「型番に対する高速なLIKE検索を行いたい」、といった用途であった場合、
Sennaの設計で想定していた問題領域と少しズレてしまいます。

なお、Sennaの内部に手を入れれば、
完全なN-gramインデックスの作成も、
アルファベット単語の後方一致検索も可能となります。




Senna-dev メーリングリストの案内
Back to archive index