TOP業務システム> 全文検索インデックスの構成オプション
Ludia
高性能なオープンソース全文検索システム「Ludia」

第5回:Ludiaの多彩な検索機能の秘密

著者:NTTデータ  岩崎 正剛   2007/2/13
前のページ  1  2  3   4  次のページ
全文検索インデックスの構成オプション

   ここで、先ほど作成したインデックスを削除し、今度は2-gramで単語を分解するインデックスを作成します。前回は"fulltext"と指定したインデックスアクセス名を、「fulltextb」に変更します。
# DROP INDEX idx;
DROP INDEX
# CREATE INDEX idx ON tbl USING fulltextb (txt);
CREATE INDEX

   ここで、部分一致検索のときと同じクエリを実行してみます。

# SELECT txt FROM tbl WHERE txt @@ ('こんに OR さようなら');
          txt
------------------------
こんにちは、さようなら
こんにちは
さようなら
(3 rows)

   fulltextインデックスの時は「こんに」というキーワードで検索しても(部分一致検索が行われない限り)ヒットしなかった「こんにちは」という行が、今回は結果に含まれています。これは、2-gramを利用するfulltextbインデックスの場合には、「こん」「んに」というトークンが両方とも含まれていてかつ、それらが連続した位置にあるということが調べられるためです。

   つまりfulltextbインデックスを利用する場合、1文字を検索キーワードとして指定しない限り、部分一致検索は必要ないことになります。しかしここでも例外があります。テーブルに以下のような行を追加してみてください。

# INSERT INTO tbl VALUES ('hello, world');
INSERT 0 1

   ここで検索実行をしてみると、部分一致検索が行われないと、いま追加した行は検索にヒットしないことがわかります。

# SELECT txt FROM tbl WHERE txt @@ ('hello OR さようなら');
          txt
------------------------
さようなら
こんにちは、さようなら
(2 rows)

# SELECT txt FROM tbl WHERE txt @@ ('hello');
     txt
--------------
hello, world
(1 row)

   これはfulltextbインデックスでは半角英数字は2文字単位に分解されないという設定になっているからです。半角英数字の場合は単語の分割は空白文字で行われるので、「hello, world」は「hello,」と「world」の2つの単語になります(「hello」ではなく「hello,」で1つの単語です)。

# SELECT txt FROM tbl WHERE txt @@ ('hello, OR さようなら');
          txt
------------------------
さようなら
hello, world
こんにちは、さようなら

   このような設定は、半角英数字まで2-gramで分割すると、多くの場合検索結果が多くなりすぎてしまう、という考え方にもとづいています。

   この設定についても、必要であれば変更することができます。全文検索インデックスの作成時には、フラグの値を与えることで、そのインデックスの設定を指定します。利用できるフラグには以下のようなものがあります(フラグの名前の右側には、その値が16進数で示されています)。

SEN_INDEX_NORMALIZE (0x0001)
英文字の大文字/小文字、全角文字/半角文字を正規化してインデックスに登録する。
SEN_INDEX_SPLIT_ALPHA (0x0002)
N-gramインデックスで正規化を指定した際、英文字列もn文字の要素に分割する(それ以外の場合は連続した英文字列を1単語とする)。
SEN_INDEX_SPLIT_DIGIT (0x0004)
N-gramインデックスで正規化を指定した際、数字文字列もn文字の要素に分割する(それ以外の場合は連続した数字文字列を1単語とする)。
SEN_INDEX_SPLIT_SYMBOL (0x0008)
N-gramインデックスで正規化を指定した際、記号文字列もn文字の要素に分割する(それ以外の場合は、連続した記号文字列を1単語とする)。
SEN_INDEX_NGRAM (0x0010)
(形態素解析ではなく)n-gramを用いる
SEN_INDEX_DELIMITED (0x0020)
(形態素解析ではなく)空白区切りで単語を区切る。

表2:全文検索時に利用できるフラグ

   fulltextインデックスはSEN_INDEX_NORMALIZEというフラグを、fulltextbインデックスはSEN_INDEX_NORMALIZE|SEN_INDEX_NGRAMというフラグを指定したものになっています。

   ここでfulltextuというインデックスメソッドを利用すると、任意のフラグを与えることができます。フラグを10進数で表現した値をludia.sen_index_flagsというLudiaのカスタム変数にセットすることで指定します。例として、英文字列を分割するために、SEN_INDEX_NORMALIZE|SEN_INDEX_NGRAM|SEN_INDEX_SPLIT_ALPHAというフラグを指定してみます(このフラグを10進数で表現した値は1+16+2=19です)。

# SET ludia.sen_index_flags TO 19;
SET
# CREATE INDEX idx ON tbl USING fulltextu (txt);
CREATE INDEX

   このインデックスで先ほどと同じ検索をしてみると、部分一致検索が行われていなくても、「hello, world」という行が結果に含まれるようになります。

# SELECT txt FROM tbl WHERE txt @@ ('hello OR さようなら');
          txt
------------------------
さようなら
hello, world
こんにちは、さようなら
(3 rows)

   全文検索エンジンは膨大な数の文書から検索を行うためのものです。そのために解決すべき重要な課題は検索を高速で行うことと、多すぎる検索結果から必要のないもの(ノイズ)を取り除くことです。

   したがって、インデックスサイズが小さく検索も高速な形態素解析による単語インデックスを作り必要があれば部分一致検索で再現率をあげる、あるいは2-gramを利用する場合でも半角英数文字列を分解しない、というデフォルトの設定は多くの場合に適したものだと思われます。

   設定の変更が本当に必要になるケースは少ないのではないでしょうか。しかし意図した通りに、効果的に、全文検索エンジンを利用するためには、こうした細かい設定による違いがあるということを知っておくことも必要です。

前のページ  1  2  3   4  次のページ


株式会社NTTデータ 岩崎 正剛
著者プロフィール
株式会社NTTデータ  岩崎 正剛
基盤システム事業本部 オープンソース開発センタ
2002年よりNTTデータにてPCグリッドの研究開発などに従事。2006年よりOSS分野に参画し、現在はLudiaの開発、技術支援を行っている。


INDEX
第5回:Ludiaの多彩な検索機能の秘密
  Ludiaの検索機能
  部分一致検索
全文検索インデックスの構成オプション
  検索スコアの取得