Amazon Aurora の MySQL 5.7 互換で全文検索を試してみた

Amazon Aurora

先日、Aurora の MySQL 5.7 互換が正式リリースされました。

Aurora の MySQL 5.7 互換からデフォルトのプラグインとして ngram が入っているようなので、全文検索を試してみました。

ngram を確認する

インスタンスを立ち上げたら、とりあえずバージョンを確認してみましょう。

mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.7.12    |
+-----------+
1 row in set (0.01 sec)

mysql> select @@aurora_version;
+------------------+
| @@aurora_version |
+------------------+
| 2.01             |
+------------------+
1 row in set (0.00 sec)

Aurora のバージョンは 2.01 であることが確認できたので、次は、プラグイン一覧を見て ngram がアクティブになっているかも確認します。

mysql> show plugins;
+----------------------------+----------+--------------------+-------------+-------------+
| Name                       | Status   | Type               | Library     | License     |
+----------------------------+----------+--------------------+-------------+-------------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL        | GPL         |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL        | GPL         |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_SCHEMA_HISTORY  | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_TABLES_HISTORY  | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_COLUMNS_HISTORY | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_INDEXES_HISTORY | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_FIELDS_HISTORY  | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL         |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL        | GPL         |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL         |
| ngram                      | ACTIVE   | FTPARSER           | NULL        | GPL         |
| AWSAuthenticationPlugin    | ACTIVE   | AUTHENTICATION     | aws_auth.so | PROPRIETARY |
+----------------------------+----------+--------------------+-------------+-------------+
50 rows in set (0.02 sec)

ngramACTIVE になっていることも確認できました。

全文検索を試してみる

テスト用として都道府県名を name カラムにもつ、prefs テーブルを作ります。

mysql> CREATE TABLE prefs (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    name VARCHAR(255),
    FULLTEXT (name) WITH PARSER ngram
) ENGINE=InnoDB CHARACTER SET utf8mb4;

FULLTEXT (name) WITH PARSER ngram という部分が、ngram を使って name カラムを全文検索の対象にするという意味になります。

対象のカラムを増やしたい場合はカンマつなぎで FULLTEXT (foo, bar, baz) WITH PARSER ngram といったかたちにします。

それでは、prefs テーブルにデータをインサートしていきます。

mysql> INSERT INTO prefs (name) VALUES
("北海道"),
("青森県"),
("岩手県"),
("宮城県"),
("秋田県"),
("山形県"),
("福島県"),
("茨城県"),
("栃木県"),
("群馬県"),
("埼玉県"),
("千葉県"),
("東京都"),
("神奈川県"),
("新潟県"),
("富山県"),
("石川県"),
("福井県"),
("山梨県"),
("長野県"),
("岐阜県"),
("静岡県"),
("愛知県"),
("三重県"),
("滋賀県"),
("京都府"),
("大阪府"),
("兵庫県"),
("奈良県"),
("和歌山県"),
("鳥取県"),
("島根県"),
("岡山県"),
("広島県"),
("山口県"),
("徳島県"),
("香川県"),
("愛媛県"),
("高知県"),
("福岡県"),
("佐賀県"),
("長崎県"),
("熊本県"),
("大分県"),
("宮崎県"),
("鹿児島県"),
("沖縄県");

テストデータのインサートが完了したら早速全文検索を試してみましょう。

まずは 京都 という文字で検索してみます。

mysql> SELECT * FROM prefs
WHERE
MATCH (name) AGAINST ("+京都" IN BOOLEAN MODE);
+----+-----------+
| id | name      |
+----+-----------+
| 13 | 東京都    |
| 26 | 京都府    |
+----+-----------+
2 rows in set (0.01 sec)

京都 という文字が入る 東京都京都府 が取得できました!

東京京都 のどちらの文字も入る都道府県を検索したい場合は +東京 +京都 として検索します。

mysql> SELECT * FROM prefs
WHERE
MATCH (name) AGAINST ("+東京 +京都" IN BOOLEAN MODE);
+----+-----------+
| id | name      |
+----+-----------+
| 13 | 東京都    |
+----+-----------+
1 row in set (0.01 sec)

東京 という文字は除外し、京都 という文字が入る都道府県を検索したい場合は -東京 +京都 として検索します。

mysql> SELECT * FROM prefs
WHERE
MATCH (name) AGAINST ("-東京 +京都" IN BOOLEAN MODE);
+----+-----------+
| id | name      |
+----+-----------+
| 26 | 京都府    |
+----+-----------+
1 row in set (0.02 sec)

まとめ

Amazon AuroraMySQL 5.7 互換ではデフォルトで ngram プラグインが入っているので、とても簡単に全文検索をすることができました。

MySQL 5.7 互換となり、他にも JSON のサポートなど新しい機能があるので、どんどん試していきたいと思います。

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版