Database JUNKY

MySQL,MariaDBを中心としたブログです

mysql: 全文検索エンジンを使ってみる : senna/Tritonnの利用

ここのwordpress全文検索エンジン入れたらきっと速くなると近いつつ、インストールしてみました。インストールは意外と簡単(むしろ調べるのに時間がかかったかな?)でした。そもそもsennaって何?なんですが、sennaサイトの文言をそのまま引用しておきます。

sennaは組み込み型の全文検索エンジンです。DBMSスクリプト言語処理系等に組み込むことによって、その全文検索機能を強化することができます。 n-gramインデックスと単語インデックスの特徴を兼ね備えた、高速かつ高精度な転置インデックスタイプのエンジンです。コンパクトな実装ですが、大規 模な文書量と検索要求を処理できるよ うに設計されています。また、純粋なn-gramインデックスの作成も可能です。

実際MySQLでも標準で全文検索エンジンはついておりますが、あえてsennaを入れてみたのは・・・。上司からの依頼ってだけで、たいした理由はないです(汗 でも簡単につかってみて、これは色々使えそうだな?と感じましたよ。 では、さっそくインストール方法について掲載します。

senna,セナ、せなって書きましたが実際こちらで説明するのは、MySQL バインディングの方法です。そのバインディングプロジェクトを、Tritonn (トリトン、トライトン)といいます。こちらの内容もサイトそのまま引用しますが

TritonnMySQLから全文検索エンジンSennaを利用可能にするための改造を行うプロジェクトです。以前はMySQLに当てるパッチを開発するプロジェクトでしたが、現在は1歩進めてMySQLの改造版ソースを開発するプロジェクトとして活動しています。

ですです。

インストール方法

[shell] MySQL-client-5.0.87-tritonn.1.0.12a.x86_64.rpm MySQL-devel-5.0.87-tritonn.1.0.12a.x86_64.rpm MySQL-server-5.0.87-tritonn.1.0.12a.x86_64.rpm MySQL-shared-5.0.87-tritonn.1.0.12a.x86_64.rpm mecab-0.98-tritonn.1.0.12a.x86_64.rpm mecab-ipadic-2.7.0.20070801-tritonn.1.0.12a.x86_64.rpm senna-1.1.4-tritonn.1.0.12a.x86_64.rpm [/shell]

MySQL 環境設定

  • mysqlの起動 [shell]

    /etc/init.d/mysql start

    /sbin/chkconfig mysql on

    /etc/init.d/mysql stop

    cp /usr/share/mysql/my-large.cnf /etc/my.cnf

    [/shell]

  • my.cnfの設定 [shell] skip-character-set-client-handshake default-character-set = utf8 character-set-server = utf8 collation-server = utf8_general_ci init-connect = SET NAMES utf8 [/shell]

初回設定

h3. mysqlの確認

  • 文字コード [shell] mysql> show variables like "char%"; +--------------------------+----------------------------+ | Variable_name            | Value                      | +--------------------------+----------------------------+ | character_set_client     | utf8                       | | character_set_connection | utf8                       | | character_set_database   | utf8                       | | character_set_filesystem | binary                     | | character_set_results    | utf8                       | | character_set_server     | utf8                       | | character_set_system     | utf8                       | | character_sets_dir       | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ [/shell]

  • engine [shell] mysql> show engines; +------------+----------+----------------------------------------------------------------+ | Engine     | Support  | Comment                                                        | +------------+----------+----------------------------------------------------------------+ | MyISAM     | DEFAULT  | Default engine as of MySQL 3.23 with great performance         | | MEMORY     | YES      | Hash based, stored in memory, useful for temporary tables      | | InnoDB     | YES      | Supports transactions, row-level locking, and foreign keys     | | BerkeleyDB | NO       | Supports transactions and page-level locking                   | | BLACKHOLE  | YES      | /dev/null storage engine (anything you write to it disappears) | | EXAMPLE    | YES      | Example storage engine                                         | | ARCHIVE    | YES      | Archive storage engine                                         | | CSV        | YES      | CSV storage engine                                             | | ndbcluster | DISABLED | Clustered, fault-tolerant, memory-based tables                 | | FEDERATED  | DISABLED | Federated MySQL storage engine                                 | | MRG_MYISAM | YES      | Collection of identical MyISAM tables                          | | ISAM       | NO       | Obsolete storage engine                                        | +------------+----------+----------------------------------------------------------------+ [/shell]

  • ユーザー情報の作成 [shell] delete from mysql.user where password = '';

set password for root@localhost=password('senna'); set password for root@127.0.0.1=password('senna');

grant all privileges on . to root@'192.168.0.0/255.255.255.0' IDENTIFIED BY 'senna';

grant SELECT,INSERT,UPDATE,DELETE on . to srdsys@'localhost' IDENTIFIED BY 'senna'; grant SELECT,INSERT,UPDATE,DELETE on . to srdsys@'127.0.0.1' IDENTIFIED BY 'senna';

grant SELECT on . to srdusr@'localhost'IDENTIFIED BY 'senna'; grant SELECT on . to srdusr@'127.0.0.1' IDENTIFIED BY 'senna'; [/shell]

  • 設定が反映されているか確認する [shell] select user,host,password from mysql.user order by user,host; [/shell]

h3. senna 検証

  • mysqlにログインする [shell] mysql -u root -psenna create database sennadb; use sennadb; [/shell]
  • NGRAMインデックスの作成 [shell] CREATE TABLE tngram ( id INTEGER AUTO_INCREMENT, PRIMARY KEY (id), yubin char(10) NOT NULL, add1 TEXT NOT NULL, add2 TEXT NOT NULL, add3 TEXT NOT NULL, FULLTEXT INDEX USING NGRAM, SECTIONALIZE (add1,add2,add3) );

設定確認

show create table tngram; CREATE TABLE tngram ( id int(11) NOT NULL auto_increment, yubin char(10) NOT NULL, add1 text NOT NULL, add2 text NOT NULL, add3 text NOT NULL, PRIMARY KEY  (id), FULLTEXT KEY add1 USING NGRAM, NORMALIZE, SECTIONALIZE, 512 (add1,add2,add3) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 [/shell] * テストデータ投入 [shell]

mysql sennadb -u root -psenna < /tmp/address.sql

[/shell] * 検索の検証 [shell]

スコアを表示してみる。

mysql> select match(add1,add2,add3) against("新宿") as score, add1,add2,add3 from tngram where match(add1,add2,add3) against("新宿") limit 10; +-------+-----------+-----------+--------------------------------+ | score | add1      | add2      | add3                           | +-------+-----------+-----------+--------------------------------+ |     1 | 東京都 | 葛飾区 | 新宿                         | |     1 | 東京都 | 新宿区 | 以下に掲載がない場合 | |     1 | 東京都 | 新宿区 | 愛住町                      | |     1 | 東京都 | 新宿区 | 赤城下町                   | |     1 | 東京都 | 新宿区 | 赤城元町                   | |     1 | 東京都 | 新宿区 | 揚場町                      | |     1 | 東京都 | 新宿区 | 荒木町                      | |     1 | 東京都 | 新宿区 | 市谷加賀町                | |     1 | 東京都 | 新宿区 | 市谷甲良町                | |     1 | 東京都 | 新宿区 | 市谷砂土原町             | +-------+-----------+-----------+--------------------------------+ 10 rows in set (0.00 sec) [/shell]

  • 重みを付けて検索してみる [shell] mysql> SELECT * FROM tngram WHERE MATCH(add1,add2,add3) AGAINST("*W1,2 新宿" IN BOOLEAN MODE) limit 10; +------+---------+-----------+-----------+--------------------------------+ | id   | yubin   | add1      | add2      | add3                           | +------+---------+-----------+-----------+--------------------------------+ | 1343 | 1600000 | 東京都 | 新宿区 | 以下に掲載がない場合 | | 1344 | 1600005 | 東京都 | 新宿区 | 愛住町                      | | 1345 | 1620803 | 東京都 | 新宿区 | 赤城下町                   | | 1346 | 1620817 | 東京都 | 新宿区 | 赤城元町                   | | 1347 | 1620824 | 東京都 | 新宿区 | 揚場町                      | | 1348 | 1600007 | 東京都 | 新宿区 | 荒木町                      | | 1349 | 1620062 | 東京都 | 新宿区 | 市谷加賀町                | | 1350 | 1620856 | 東京都 | 新宿区 | 市谷甲良町                | | 1351 | 1620842 | 東京都 | 新宿区 | 市谷砂土原町             | | 1352 | 1620846 | 東京都 | 新宿区 | 市谷左内町                | +------+---------+-----------+-----------+--------------------------------+ 10 rows in set (0.00 sec) [/shell]