[groonga-dev,01307] Re: utf8_unicode_ciカラムでのLIKE検索時の挙動について

アーカイブの一覧に戻る

Kouhei Sutou kou****@cozmi*****
2013年 4月 21日 (日) 19:17:19 JST


須藤です。

In <42057****@web10*****>
  "[groonga-dev,01304] utf8_unicode_ciカラムでのLIKE検索時の挙動について" on Sun, 21 Apr 2013 11:57:03 +0900 (JST),
  <mail_babir****@yahoo*****> wrote:

> また、もう一点、前回と同一原因かは不明ですが、utf8_unicode_ci時のLIKE検索において、動作に問題があるようでしたので、ご連絡させて頂きます。
> 
> 具体的には、utf8_unicode_ci使用時のLIKE検索前方一致において、検索条件に完全一致した場合の結果が含まれないというものです。

こちらでも再現したので確認しました。
ちょっと、直し方を考えないといけないので、回避策を紹介します。

まず、INDEXをFULLTEXT INDEXにして、parserをTokenDelimitNull
にします。本当はparserなしにしたいのですが、今はそれはできな
いのでTokenDelimitNullで代用しています。

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `main` varchar(255) NOT NULL COLLATE 'utf8_unicode_ci',
  PRIMARY KEY (`id`),
  FULLTEXT INDEX main (`main`)  COMMENT 'parser "TokenDelimitNull"'
) ENGINE=mroonga DEFAULT CHARSET=utf8;

検索するときはLIKEではなくMATCH AGAINSTを使うのですが、検索
語の最後に「*」をつけてください。これで、groongaの前方一致検
索機能を使えます。

SELECT * FROM  `test` WHERE MATCH(`main`) AGAINST('とらっく*' IN BOOLEAN MODE);

処理を確認したらLIKEのときでもインデックスを使ってましたが、
MATCH AGAINSTでもインデックスを使うので、同じくらい速く動く
はずです。


以下、調べた内容のメモです。

MySQLはVARCHAR(N)など、サイズが決まっている文字列のときは文字
列の足りない部分(右側の余っている部分)を埋めるのですが、確
認してみたところ、utf8_unicode_ciの場合はタブ文字(U+0009)で
埋めるようです。
utf8_general_ciの場合はU+0000で埋めるようです。

一方、groongaは可変長文字列として扱い、何かの文字で埋めるよ
うなことはしていません。つまり、groongaのインデックスには
「とらっく」と「とらっくばっく」が入っています。

MySQLは「とらっく\t\t\t\t\t...」という文字列より大きい文字列
というリクエストをmroongaに渡してきます。utf8_general_ciの場
合は「とらっく\0\0\0\0...」を渡してきます。

groongaは「とらっく\0\0\0\0...」を指定された場合は「とらっく」
を大きい値をみなしますが、「とらっく\t\t\t\t...」を指定され
た場合は「とらっく」を小さい値とみなしてヒットさせません。

なので、utf8_general_ciのときはヒットしてutf8_unicode_ciのと
きはヒットしません。

うーん、どうするのがいいのかしら。右側にある
field->charset()->min_sort_charを全部\0に置き換えちゃうのがよ
い気がするけど。。。


-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

groongaサポート:
  http://groonga.org/ja/support/
パッチ採用はじめました:
  http://www.clear-code.com/recruitment/
コミットへのコメントサービスはじめました:
  http://www.clear-code.com/services/commit-comment.html




groonga-dev メーリングリストの案内
アーカイブの一覧に戻る