Naoya Murakami
visio****@gmail*****
2013年 8月 30日 (金) 07:11:55 JST
お世話になっております。村上です。
1.grn_str_charlen_utf8(): imcomplete character
このメッセージが出力されるケースが特定できました。
ベクターカラムに対して、"区切り文字データなし"をinsertした後に、
selectすると、うまくデータを取得できません(NULLが入るんですかね)。
これをinsert into A select * from Bすると、このメッセージが発生します。
ベクターカラムに投入したデータに問題があったようです。
既存のテーブルをgroup_concatしただけで、結構、
"データ1区切り文字区切り文字データ2"となっているケースがあったので、
投入するデータをチェックして、区切り文字の後にデータがない状態が
発生しないようにしてベクターカラムに投入したいと思います。
"データ1区切り文字区切り文字データ2"をinsertとすると、
データ2(下のケースだと"ぐるんが")が無視されますが、
この挙動が正しいのかどうかよくわかりません。よければ、ご検討ください。
投入の仕方に問題があると思うので、mroonga,groongaでどういう挙動させる
かは、ご判断次第かと思います。
データなしを無視して、データ1とデータ2だけを入れることができるとあまり
投入仕方を意識しなくてよいので楽ですが、この挙動が正しいかといわれる
とよくわかりません。
mysql> INSERT INTO Bugs (id, tags) VALUES (1, "りなっくす ぐるんが");
mysql> INSERT INTO Bugs (id, tags) VALUES (2, "ユニックス ");
mysql> INSERT INTO Bugs (id, tags) VALUES (3, "ウィンドウズ ポルンガ タッカラプトプピリットパロ");
mysql> select * from Bugs;
+----+-------------------------------------------------------------------------+
| id |
tags |
+----+-------------------------------------------------------------------------+
| 1 | りなっくす ・ |
| 2 | ユニックス ・ |
| 3 | ウィンドウズ ポルンガ タッカラプトプピリットパロ |
+----+-------------------------------------------------------------------------+
mysql> select mroonga_command('select --table Bugs');
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mroonga_command('select --table
Bugs')
|
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
[[[3],[["_id","UInt32"],["_key","UInt32"],["id","UInt32"],["tags","Tags"]],[1,1,1,["りなっくす",""]],[2,2,2,["ユニックス",""]],[3,3,3,["ウィンドウズ","ポルンガ","タッカラプトプピリットパロ"]]]]
|
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> insert ignore into Bugs2 select * from Bugs;
・groonga.log
2013-08-30 03:21:39.277841|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.277965|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278492|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278522|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278642|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278665|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278685|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278697|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2. grn_str_charlen_utf8(): first byte is invalid
こちらについては、多数の自然文書を喰わせている以上、稀に不正な文字が
含まれるのも仕方のないことかなぁと考えています。
逐一調べて、前処理で不正な文字を処理するのもあまり現実的ではないかな
と考えています。どんな不正な文字が含まれているのかを特定するのも大変
そうです。
>例えば、以下のように不正なUTF-8文字を含んでいる場合、
> Hel${不正なUTF-8文字}lo World
>「lo World」以降は無視される処理になっていることがほとんどなはずです。
このような不正文字は、おそらく文章の途中で区切られているケースはあまり
ないと思われます。
なので、以下のようにトークナイズしてくれていたら影響が少なくうれしいなと
思っています。それとも、やはり後ろに続くHello World.まで無視されてしまう
のですかね。。
Good Bye World.${不正なUTF-8文字}Hello World.
↓
Good | Bye | World | . | Hello | World | .
トークンを切り出した後に無視されるのか、それとも文章に不正文字が1つでも
含まれていたら、不正文字の後の全部が無視されるのかで影響度がかなり違うので、
このあたりを知りたいなぁと思ってます。
たとえば、数千文字の文章で先頭1文字目で不正文字がでてきたら、文章全体が
無視されてしまう?
このメッセージがでる文章を特定できたら、実際のトークナイズされ方を見ることが
できると思いますが、オフラインインデックス構築中に稀に見かける程度なので、
どの文章でこのメッセージがでているのかを特定するのが大変なのですよね。
この警告メッセージが出力される文章および不正文字の出現位置を簡単に
特定する方法はありますか?
ソースを一時的に書き換えてこのメッセージをエラーにしておけば、処理がとまって
特定できますかね?
それか、前に教えていただいたようにして、gdbでbreak str.c:44とかしておけば、
ブレークしてとまってくれるのですかね?
https://github.com/groonga/groonga/blob/b6f34484726019881d2466d979cc45cd3afd2c12/lib/str.c#L44
なお、照合順序をバイナリにすれば、大丈夫かもしれませんが、
レアケースのために、照合順序をバイナリにすることは考えていません。
---------------------------------------------
以下でgrn_str_charlen_utf8(): imcomplete characterを再現することができます。
ご参考まで。
CREATE TABLE Tags (
name VARCHAR(64) PRIMARY KEY
) DEFAULT CHARSET=utf8
COLLATE=utf8_bin
COMMENT='default_tokenizer "TokenDelimit"';
CREATE TABLE Bugs (
id INT UNSIGNED PRIMARY KEY,
tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "Tags"',
FULLTEXT INDEX tags (tags) COMMENT 'table "Tags"'
) DEFAULT CHARSET=utf8;
CREATE TABLE Tags2 (
name VARCHAR(64) PRIMARY KEY
) DEFAULT CHARSET=utf8
COLLATE=utf8_bin
COMMENT='default_tokenizer "TokenDelimit"';
CREATE TABLE Bugs2 (
id INT UNSIGNED PRIMARY KEY,
tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "Tags2"',
FULLTEXT INDEX tags (tags) COMMENT 'table "Tags2"'
) DEFAULT CHARSET=utf8;
INSERT INTO Bugs (id, tags) VALUES (1, "りなっくす ぐるんが");
INSERT INTO Bugs (id, tags) VALUES (2, "ユニックス ");
INSERT INTO Bugs (id, tags) VALUES (3, "ウィンドウズ ポルンガ タッカラプトプピリットパロ");
insert ignore into Bugs2 select * from Bugs;
以上、よろしくお願いします。