Naoya Murakami
visio****@gmail*****
2014年 8月 22日 (金) 01:23:19 JST
村上です。 2014年8月21日 19:55 Kimura A <a.kim****@live*****>: > > > Windows版Mroongaでベクターカラムを使ったDBを作成し、いったんMySQLDumpしてからインポートした場合に、ベクターカラムによる検索が機能しなくなってしまい困っています。 > 以下、「mroongaでベクターカラムを使ってタグ検索を実現するには」の例に従って再現手順を書いてみます。 > http://qiita.com/groonga/items/f41cd8cfbe7bd158d5da > > 記事との違いは、以下の3点です。 > ◯テーブル名は小文字に統一:以前Windows環境で何かトラブルが起きたことがあったので。 > ◯「ENGINE=mroonga」を加筆:InnoDBになってしまうため。 > > ◯インデックス用テーブルtagsに「1_」を前置:MySQLDumpファイルからのインポート時に、tags(1_tags)がbugsより先に生成されるようにするため。 > > まずtestデータベース内に、1_tagsおよびbugsテーブルを作成します。 > > use test; > > CREATE TABLE 1_tags ( > name VARCHAR(64) PRIMARY KEY > ) DEFAULT CHARSET=utf8 > COLLATE=utf8_bin > ENGINE=mroonga > COMMENT='default_tokenizer "TokenDelimit"'; > > CREATE TABLE bugs ( > id INT PRIMARY KEY AUTO_INCREMENT, > tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "1_tags"', > FULLTEXT INDEX(tags) > ) DEFAULT CHARSET=utf8 > ENGINE=mroonga; > 記事とはFULLTEXT INDEXの作り方が異なっています。 (ちなみにこのQiitaの記事は以前誤っており編集されております。) 記事では、 FULLTEXT INDEX bugs_tags_index(tags) COMMENT 'table "Tags"' となっているのに対し、 上記では、 FULLTEXT INDEX(tags) となっています。 コメントがない方法では、ベクターカラムに対して通常の全文インデックス と同じ方法でインデックスが作成されてしまいます。 この方法では、データ追加時以外では文字列のデータを取得できない ため(Groongaではベクター型で保存されている)、オフラインでの インデックス構築ができません。 以下のスレッドで須藤さんに教えてもらいました。 http://sourceforge.jp/projects/groonga/lists/archive/dev/2013-September/001778.html mysqldumpのダンプファイルでは、 ALTER TABLE bugs DISABLE KEYS; INSERT ... ALTER TABLE bugs ENABLE KEYS; となっています。 ALTER TABLE bugs DISABLE KEYSで全文インデックス用の インデックスカラムが削除されます。 ALTER TABLE bugs ENABLE KEYSで全文インデックス用の インデックスカラムが作成されますが、ベクター型なので値を取得 できず、インデックスの中身は空のままです。 一応、ENABLEの状態でINSERTすれば、インデックスが作られるとは 思いますが、この使用方法はサポートされていないようです(上記スレッド 参照)。 Qiitaの記事のインデックスの作成方法だと、bugsのFULLTEXT インデックスにより、Groonga的にはインデックスカラムは1_tagsの 方に作成されて、bugsテーブルのtagsカラムを対象にします。 (たぶんわけがわからないと思います) この方法ならbugsテーブルでDISABLEをしても1_tagsカラムの インデックスカラムが削除されません。 なので、この状態でINSERTしてもインデックスが作成されます。 ◯上掲のような経緯でタグ検索が不可能になったDBを復旧させる方法 > Qiitaの記事の方法のように、テーブル参照型のインデックスを 張ればいい思います。こうすれば、そのままダンプファイルを リストアすることができました。 このほかのsyntaxエラー等は環境による何かだと思いますが よくわかりません。 私の場合、メールにあったものそのままコピペで通りました。 (インデックスは作成されませんが。) --- ところで、テーブル参照型のインデックスをALTER TABLE でDROP した場合、Groonga側のインデックスカラムがたどって削除されない 挙動を見つけました。 削除されていないのでもっかいつくろうとするとmysqldが死にます。 たぶん<テーブル名>-<インデックス名>の規則の語彙表削除の 処理しか入っていないんじゃないかなぁと思います。 https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L13364-L13372 おそらく、インデックス対象のカラム名をとってきて、そのカラム名に張 られているGroongaのインデックスをgrn_column_indexで探してきて、 削除する処理を追加する感じですかね。 <再現例> CREATE TABLE indexes ( memo varchar(64) NOT NULL, PRIMARY KEY (memo) )ENGINE=mroonga DEFAULT CHARSET=utf8 CREATE TABLE diaries ( id int(11) NOT NULL AUTO_INCREMENT, title text, PRIMARY KEY (id), FULLTEXT INDEX title(title) COMMENT 'table "indexes"' ) ENGINE=mroonga DEFAULT CHARSET=utf8; ALTER TABLE diaries DROP INDEX title; ALTER TABLE diaries ADD FULLTEXT INDEX title(title) COMMENT 'table "indexes"' 以上です。