Quantcast
Channel: Planet MySQL
Viewing all articles
Browse latest Browse all 1081

mroongaの正規化機能(normalizer)の挙動を追ってみる

$
0
0

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
    • 大文字-小文字を同一視する
    • 半角-全角も同一視する。
      • 数字の場合、丸数字も同一視
      • 「け」の場合「~ヶ所」のような小書きも同一視
      • 半角の濁音や半濁音も同一視

より掘り下げた内容については、以下ページをご参照下さい。

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

Viewing all articles
Browse latest Browse all 1081

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>