TOP業務システム> Ludiaの検索機能
Ludia
高性能なオープンソース全文検索システム「Ludia」

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

著者:NTTデータ  岩崎 正剛   2007/2/13
1   2  3  4  次のページ
Ludiaの検索機能

   第4回では、オープンソースの全文検索システム「Ludia」の導入を行いました。今回はLudiaを実際に動かしながら、検索機能のバリエーションについてみていきます。
Ludiaの構成

   まず、Ludiaがどのような構成になっているかをもう一度確認します。なお、Ludiaがどのような作りになっているかといった、すこし細かい説明もありますので、そこは読み飛ばして次の「基本的な検索」の説明に進んでもかまいません。

   LudiaはPostgreSQLの拡張モジュールとして、全文検索インデックス機能を提供します。「第2回:データを徹底活用する全文検索機能の仕組みと製品比較」で全文検索インデックスの説明をする際に、書籍の索引を例としてとりあげましたが、書籍の索引とは「単語 → ページ番号」という対応表のことでした。データベースのインデックスでは、これが「単語 → 行のID」という対応表になります。

   PostgreSQLのインデックスの場合、行のIDとして「ctid」というデータを利用します。ctidは、その行のデータが格納されているディスク上の物理的な位置をあらわしています。その値は次のようにクエリを発行することで確認できます。

# SELECT txt, ctid FROM tbl;
          txt           | ctid
------------------------+-------
こんにちは             | (0,1)
さようなら             | (0,2)
こんにちは、さようなら | (0,3)
(3 rows)

   これを見ると、ctidは2つの数字の組になっていますが、例えば「(0,2)」というのは0ページ目の2番目の行という意味です。なお、ここでいう「ページ」とはDBMSがディスクを管理する際に利用する単位です。PostgreSQLではMVCCという仕組みを採用している都合上、ctidはデータの更新などで変化します。このため、それを考慮したインデックスのメンテナンスが必要になりますが、それについては省略します。

   より詳しく説明すると、Ludiaは PostgreSQLと情報をやりとりして全文検索インデックスの検索や更新を行ういくつかの(インデックスアクセスメソッドの実装である)関数に加えて、検索スコアの取得やインデックスファイルの削除を行う、ユーティリティ関数から構成されています。

   また、Ludiaは「単語 → ctid」という対応表(つまり全文検索インデックス)を作るために、Sennaという全文検索エンジンを利用しています。さらに、Sennaは形態素解析を行う場合には、MeCabという形態素解析エンジンを利用しています。

   以降では、Ludiaを利用して複雑な検索を行うための準備として、簡単な文字列のデータに対して様々な種類の検索を実行してみます。実際、どのような処理で全文検索が行われているのかを見ていきましょう。


基本的な検索

   ここでは、実際に検索を実行した時、Ludiaではどのような検索条件を指定することができるのかを見ていきます。まずはその準備として、psqlコマンドでPostgreSQLを起動し、以下のようにテスト用のテーブルとインデックスを作成します。

# CREATE TABLE tbl (txt text);
CREATE TABLE
# CREATE INDEX idx ON tbl USING fulltext (txt);
CREATE INDEX
# INSERT INTO tbl VALUES ('こんにちは');
INSERT 0 1
# INSERT INTO tbl VALUES ('さようなら');
INSERT 0 1
# INSERT INTO tbl VALUES ('こんにちは、さようなら');
INSERT 0 1

   Ludiaの全文検索機能では、次のように「@@演算子」で全文検索クエリを指定することができます。これを基に、例をあげながら検索の種類を見ていきます。

SELECT txt FROM tbl WHERE txt @@ '全文検索クエリ';

   次に示すのは、Webサイト上の検索でもよく使われる検索したい単語を空白で区切る方法です。この方法では指定された単語のうち、どれかを含む行が取得できます。

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

   これは、いわゆる「OR検索」と呼ばれる検索方法です。全文検索クエリでは演算子を利用して細かい指定を行うことができますが、演算子を省略した場合のデフォルトの動作はOR検索になっています。実際、以下のように検索条件を指定しても、上記と同じことになります。

# SELECT txt FROM tbl WHERE txt @@ 'こんにちは OR さようなら';

   また、次のように「+演算子」を指定すると、両方の単語を含む行のみを取り出すことができます。

# SELECT txt FROM tbl WHERE txt    'こんにちは + さようなら';
          txt
------------------------
こんにちは、さようなら
(1 row)

   逆に、「-演算子」で指定した単語を含む行を取り除くことができます。

# SELECT txt FROM tbl WHERE txt @@ 'こんにちは - さようなら';
    txt
------------
こんにちは
(1 row)

   ここで注意が必要なのは、+演算子や-演算子を使用した場合、内部で行われる処理は検索ではなく検索結果からの除外だという点です。この例では、次に示す表の通りの動作をすることになります。よって、+演算子や-演算子を検索条件の最初にもってくることはできません(指定したとしても無視されます)。

「こんにちは + さようなら」での場合
「こんにちは」で検索して得られた結果から「さようなら」を含まないものを除外する。
「こんにちは - さようなら」の場合
「こんにちは」で検索して得られた結果から「さようなら」を含むものを除外する。

表1:+演算子と-演算子の検索動作

1   2  3  4  次のページ


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


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