mroongaの初期設定では、MySQLで利用されているCOLLATION(照合順序)とは異なる文字列の正規化を行います。
これはいわゆるgroonga独自のnormalizer(NormalizerAuto)というもので、大文字-小文字だけでなく、全角-半角を同一視できるというUnicodeのNFKCを用いた機能です。
しかし、mroongaをMySQLのストレージエンジンとして使うときに、MySQLでの作法に合わせた方が都合が良い場合があります。そこで、groonga-normalizer-mysql
というパッケージの出番です。
本記事では、それぞれの挙動の違いを追ってみたいと思います。
mroongaで使えるnormalizer
いまのところ4つのnormalizerから選択できます。
NormalizerAuto
初期設定ではこれが利用されます。大文字小文字の区別なく検索する事が出来ます。
NormalizerMySQLGeneralCI
MySQLでいうutf8mb4_general_ci
を模したノーマライザーです。
utf8_general_ci
に相当します。
NormalizerMySQLUnicodeCI
MySQLでいうutf8mb4_unicode_ci
を模したノーマライザーです。
utf8_unicode_ci
に相当します。
NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark
濁音・半濁音・「ぁ」「ぃ」「ぅ」「ぇ」「ぉ」「っ」などは区別しつつ、
カタカナとひらがなは同一視することができるノーマライザーです。
「ブラック」と「ふらつく」、「バルス」と「パルス」を区別できます。
用語説明
NormalizerAuto(groonga独自のnormalizer)の処理内容
UTF-8でエンコードされたテキストにはUnicodeのNFKC(Normalization Form Compatibility Composition)を使います。他のエンコーディング用にはエンコーディング毎に独自の正規化をします。これらの独自の正規化の結果はNFKCでの結果と似たものになります。 例えば、半角カタカナ(例えば「カ」: U+FF76 HALFWIDTH KATAKANA LETTER KA) + 半角カタカナの濁点(「゙」: U+FF9E HALFWIDTH KATAKANA VOICED SOUND MARK)は濁点付きの全角カタカナ(「ガ」: U+30AC KATAKANA LETTER GA)に正規化されます。前者は2文字ですが、後者は1文字です。 http://groonga.org/ja/docs/reference/normalizers.html#built-in-normalizers
MySQLでのutf8とutf8mb4の違い
MySQL 5.1のUTF-8では、3バイトで収まるもの、すなわち基本多言語面しか対応していなかった。現在では、UTF-8で有効な文字には4バイトのものがあり、それらは追加面と呼ばれているのだが、MySQL 5.1のUTF-8ではそれを扱うことが出来なかった。(どうしても取り扱い対場合にはVARCHARなどの文字列型の使用をやめ、BINARY型のカラムを使うという回避方法があったが、至極面倒であったと思う。)MySQL 5.5では新たに4バイトUTF-8に対応した! http://nippondanji.blogspot.jp/2010/12/mysql-55.html
MySQLでのutf8_general_ciとutf8_unicode_ciの違い
そもそもの挙動の違いとしては、以下の通りです。
- utf8_general_ci
- MySQLのデフォルト
- 大文字-小文字を同一視する
- utf8_unicode_ci
- 大文字-小文字を同一視する
- 半角-全角も同一視する。
- 数字の場合、丸数字も同一視
- 「け」の場合「~ヶ所」のような小書きも同一視
- 半角の濁音や半濁音も同一視
より掘り下げた内容については、以下ページをご参照下さい。
- mysqlのcollateを使って大文字-小文字や全角-半角を無視した検索
http://d.hatena.ne.jp/end0tknr/20100613/1276427626 - MySQLにおける、utf8_general_ci と utf8_unicode_ci の違いとは何か。
http://www.php-seed.net/blog/archives/129 - MySQL 5.5 の unicode collation で同一視される文字 - @tmtms のメモ
http://tmtms.hatenablog.com/entry/20110416/mysql_unicode_collation
mroongaで使えるnormalizerの動作確認
動作確認方法
mysql-mroonga-3.02
より対応となったUDF、mroonga_command
を用います。
これを用いてgroongaに直接クエリを投げて、どのように正規化されるか追ってみましょう。
利用するコマンド
mroongaを入れたMySQLクエリで行う場合
SELECT mroonga_command('normalize 正規化機能名 文字列');
groongaコマンドを使う場合
$ groonga > register normalizers/mysql > normalize 正規化機能名 文字列
確認結果
NormalizerMySQLGeneralCI
mysql> select mroonga_command('normalize NormalizerMySQLGeneralCI ブラックふらつくバルスパルス'); +--------------------------------------------------------------------------------------------------+ | mroonga_command('normalize NormalizerMySQLGeneralCI ブラックふらつくバルスパルス') | +--------------------------------------------------------------------------------------------------+ | {"normalized":"ブラックふらつくバルスパルス","types":[]} | +--------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
NormalizerMySQLUnicodeCI
mysql> select mroonga_command('normalize NormalizerMySQLUnicodeCI ブラックふらつくバルスパルス'); +--------------------------------------------------------------------------------------------------+ | mroonga_command('normalize NormalizerMySQLUnicodeCI ブラックふらつくバルスパルス') | +--------------------------------------------------------------------------------------------------+ | {"normalized":"ふらつくふらつくはるすはるす","types":[]} | +--------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark
mysql> select mroonga_command('normalize NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark ブラックふらつくバルスパルス'); +-------------------------------------------------------------------------------------------------------------------------------------+ | mroonga_command('normalize NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark ブラックふらつくバルスパルス') | +-------------------------------------------------------------------------------------------------------------------------------------+ | {"normalized":"ぶらっくふらつくばるすぱるす","types":[]} | +-------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
PlanetMySQL Voting: Vote UP / Vote DOWN