MySQL/PostgreSQL+Sennaで行うラクラク全文検索……Tritonn&Ludia導入のポイント

この記事を読むのに必要な時間:およそ 4.5 分

クエリ例

改変済みのMySQLは,リスト1のようなクエリで全文検索インデックスを作成することができます。

リスト1 全文検索インデックスの作成(Tritonn)

●テーブル作成時の全文検索インデックス付与
 CREATE TABLE tbl1 (
   id INTEGER AUTO_INCREMENT,
   PRIMARY KEY (id),
   text TEXT NOT NULL,
   FULLTEXT INDEX USING NGRAM (text)
 );

●既存のテーブルtbl1のカラムtextへの全文検索インデックス付与
 ALTER TABLE tbl1 ADD FULLTEXT INDEX ft USING NGRAM (text);

リスト1のクエリにて,テーブルtbl1のカラムtextに全文検索インデックスが付与されました。以下のクエリで全文検索を行うことができます。

 SELECT * FROM tbl1 WHERE MATCH(text) AGAINST('検索クエリ');

また,Yahoo!やGoogleのように,AND検索やOR検索などをサポートする場合には以下のようなクエリを実行します。

 SELECT * FROM tbl1 WHERE MATCH(text) AGAINST('検索クエリ' IN BOOLEAN MODE);

IN BOOLEAN MODEを指定して,検索クエリ内にスペースで区切られた複数の単語が存在したとします。この場合,Yahoo!やGoogleではAND検索が行われますが,TritonnではOR検索が行われます。デフォルトでAND検索を行うためには,以下のように検索クエリの頭に「*D+」を付与してください。

 SELECT * FROM tbl1 WHERE MATCH(text) AGAINST('*D+ 検索クエリ' IN BOOLEAN MODE);

もちろん,他カラムを用いての絞込みやソートを行うことが可能です。

 SELECT * FROM tbl1 WHERE MATCH(text) AGAINST('*D+ 検索クエリ' IN BOOLEAN MODE) AND id < 1000 ORDER BY id;

また,検索結果のスコアも取得することができます。MATCH~AGAINSTの部分を関数のように扱うことにより,スコアを取得することができます。

 SELECT id, MATCH(text) AGAINST ('*D+ 検索クエリ') AS score FROM tbl1 WHERE MATCH(text) AGAINST('*D+ 検索クエリ' IN BOOLEAN MODE);

Tritonn使用上のTips

Tritonnを使用する上で,知っておくとうれしい(!?)事項を4つ紹介いたします。

1)インデックス利用の注意点と2ind機能

Tritonnでは,データベースのインデックスを利用する際に留意することがあります。MySQLでは,EXPLAINコマンドを利用することによって,インデックスがどのように利用されているかを確認することができます。しかし,Tritonnで付与された全文検索インデックスが利用されているかどうかは,EXPLAINコマンドでは現状わかりません。よって,全文検索句であるMATCH AGAINSTを除いたクエリをEXPLAINコマンドで解析し,インデックスが利用されていることを確認しましょう。

そして,全文検索インデックスとEXPLAINコマンドで使われていることが確認されたインデックスとを組み合わせるためには,Tritonnの「2ind」と呼ばれる機能を有効にすることが必要となります。

MySQLの設定ファイルであるmy.cnfの[mysqld]というセクションに以下の1行を追加することによって,2ind機能を有効にすることができます。

 senna_2ind

また,MySQLへの接続ごとに,以下のクエリを実行することによっても2ind機能を有効にすることができます。

 SET SESSION senna_2ind=ON;
2)検索応答のスループット

クライアントの数が多くなるにつれ,検索応答のスループットが落ち込みます。そのような場合には,複数台のサーバ上でTritonnを動かし,ユーザからの問い合わせを振り分ける必要があります。Tritonnはレプリケーションに対応しているため,レプリケーションのスレーブ側のサーバを複数台用意することをお勧めいたします。

3)検索結果の取得の処理

検索結果のすべてを取得する処理は大変時間がかかります。SELECT文においてLIMITを指定することによって,必要な検索結果のみを取得しましょう。その際に,検索結果の総件数を得るためにはSQL_CALC_FOUND_ROWSオプションとFOUND_ROWS()という関数を利用することができます。詳しくは,MySQLのリファレンスマニュアルをご覧ください。

4)kwic()関数

kwic()関数を利用することによって,Webの検索エンジンのように,コンテンツ中の検索語の前後にHTMLタグ等を付与して目立たせることができるようになります。詳細は,Tritonnの公式ページにあるドキュメントをご覧ください。

Ludia

インストール

Ludiaのインストール方法について説明します。MeCabとSenna,そしてPostgreSQL 8.1/8.2のいずれかのバージョンがインストールされていることを前提とします。

まず,Ludiaのアーカイブを展開し,以下の要領でインストールを行います。

 ./configure
 make
 make install//root権限で

pg_configコマンドやsenna_cfgコマンドのインストール先が環境変数PATHに指定されていない場合は,configure時に明示的な指定が必要となります。たとえば,pg_configが/usr/local/pgsql/bin/pg_configに存在し,senna_cfgが/usr/local/bin/senna-cfgに存在する場合には,以下のようなオプションを指定してconfigureを実行します。

 ./configure --with-pg-config=/usr/local/pgsql/bin/pg_config \
              --with-senna-cfg=/usr/local/bin/senna-cfg

次に,Ludiaを使用するデータベースにおいて,インデックスアクセスメソッドと呼ばれるものを定義します。たとえば,データベースtdbに対して定義するには,以下のようなコマンドを実行します。

 psql -f /usr/local/pgsql/share/pgsenna2.sql tdb

pgsenna2.sqlはPostgreSQLのshareディレクトリにインストール されています。

著者プロフィール

末永匡(すえなが たすく)

(有)未来検索ブラジル所属。仮想通貨や検索エンジンやテンプレートエンジンなど,いろんなものをいろんな言語で開発している。グニャラくんと呼ばれている。

URLhttp://d.hatena.ne.jp/tasukuchan/

コメント

  • Tritonn導入につきまして

    大変参考にさせていただいております。
    現在Tritonn使用を考えているのですが、今迄使用してきたMysqlのデータを保持したままTritonnを導入できるものなのでしょうか?初歩的な質問かもしれませんが教えていただけると幸いです。よろしくお願いいたします。

    Commented : #1  kamiya (2008/04/01, 23:50)

コメントの記入