[groonga-dev,01650] Re: mroongaストレージモードの複数インデックスを使用した検索について

Back to archive index

Kouhei Sutou kou****@clear*****
2013年 8月 20日 (火) 15:20:23 JST


須藤です。

In <CANM+HhcZRHbzyG+-aay1ntv=Np-eKWfc=xzqtqKGEnT5E_=D7g****@mail*****>
  "[groonga-dev,01649] Re: mroongaストレージモードの複数インデックスを使用した検索について" on Mon, 19 Aug 2013 23:22:57 +0900,
  Naoya Murakami <visio****@gmail*****> wrote:

> 1.ベクターカラムについて
> 
> ベクターカラムを少しだけ触ってみました。
> 参照先のテーブルの語彙は各レコードで共有される、参照元でDELETE、UPDATEしても、
> 参照先のテーブルの語彙は消えない、等、若干くせのある挙動をしますが、
> mroongaでベクターカラムのドリルダウンができるようになってすばらしいです!

あぁ、参照先のテーブルはインデックスみたいなものだと考えてく
ださい。参照元のデータの更新だけ考えて、参照先のことは考慮し
なくてよいです。

> 少し使っただけですが、以下の点が気になりました。
> 
> ・キーのリファレンス指定(?)を間違えると、mysqldがクラッシュします。
> 例:
> 参照先テーブル名:reference
> 参照元テーブルでのキー指定:KEY `ref` (`ref`) COMMENT 'table "referenc"'

そんなこともあるだろうなぁと思います。。。
見ておきます。。。

> ・以下のようにインデックスにテーブルを指定すると、参照元のテーブルに
> 参照先のレコードをもとにしたキーが生成されるのでしょうか?
> キーサイズが大きくなり、キーサイズ合計の4G制限がさらにこわくなってくるなぁと感じました。
> KEY `ref` (`ref`) COMMENT 'table "reference"'

いえ、違います。これは、参照先のテーブル(reference)に参照元
のカラム(ref)の値をもとにしたキーが生成されます。refの1つ1
つの値が大きくて種類も多いと4GBの制限に到達するかもしれませ
ん。と書いて伝わるかどうかがわかりませんが。。。

例えば、

https://github.com/mroonga/mroonga/blob/master/test/sql/suite/mroonga/storage/fulltext/groonga/t/varchar_vector.test

にある

  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 VARCHAR(40) COMMENT 'type "Tags", flags "COLUMN_VECTOR"',
    FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "Tags"'
  ) DEFAULT CHARSET=utf8;

だと、

  FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "Tags"'

で

  column_create Tags bugs_tags_index COLUMN_INDEX|WITH_POSITION Bugs tags

というgroongaのインデックスができます。

> ・参照元テーブルのカラムのレコード長は、あらかじめ長めにとっておく必要があり、
> また、キーの4Kbyte制限もかかってくるので、長い文字列やあまりの多数の
> レコードの格納には不向きだなと感じました。

はい、その通りです。

> ・TokenDelimitだけだと、英文等空白を含む文字列を扱えないため、ベクターカラムを使うに
> あたっては、セミコロン等、多少区切り文字のバリエーションがあると嬉しいと感じました。

トークナイザーにパラメーターを渡せるようにしたいなぁという話
はでるのですが、まだ実現できてません。。。

> TokenDelimitを1文字変えるだけで実装できたので、当方はTokenDelimitSemiColon
> というトークナイザを作ってベクターカラムを構成しました。

おぉ。TokenDlimitNullという'\0'区切りのやつが組み込みであるの
ですが、それでもよいかもしれませんね。

> しかし、こうすると、selectは空白区切りで出力され、insert,updateはセミコロンという
> ちぐはぐになりました。。でも、便利なので、セミコロンで使おうと思ってます。

たぶん、ここの' 'を';'にするとセミコロン区切りになります。
  https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L9808

が、汎用的ではないんですよねぇ。

> ・ベクターカラムのドリルダウン便利だなぁと思ったのですが、複数のテーブルを
> 横断してのドリルダウンは難しいですよね?
> できるのは、ドリルダウンソートしてアプリケーション側で足しこむぐらいかなぁと思っています。

イメージがわかないのですが、たぶん、できないと思います。アプ
リケーション側での対応になると思います。

> 2.order by limit の高速化について
> 
>>別の方法として、AGAINST("..." IN BOOLEAN MODE)の中でgroonga
>>の検索条件を指定するという方法があります。
> 
> この方法を試したのですが、うまくAND条件で絞り込むことができませんでした。

むむ。

> varchar equalのorder by limitのoptimizationを追加していただいたことにより、
> where match ... against and varchar = "hogehoge"の形では、
> order by の最適化が動くようになりました!ありがとうございました!

おぉ、もう気づいているとは。。。!

> (4)AGAINST("..." IN BOOLEAN MODE)の中で全文検索+前方一致検索条件を指定
> select app_id from ftext_199x where
> match(title,abstract,claims,description) against ("device
> varchar:hogehoge*" in boolean mode) order by int limit 1,10;
> 0.889sec
> 後ろの条件で絞り込めない

すみません。。。

「カラム名:値」という書式は無効化してありました。。。

  https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L7686

の
  GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
に
  | GRN_EXPR_ALLOW_COLUMN
を足して
  GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT | GRN_EXPR_ALLOW_COLUMN;
とすれば「カラム名:値」が使えるようになります。

あと、BOOLEAN MODEはデフォルトでORなので↓のように最初に「+」
をつけないといけません。

  "device +varchar:hogehoge*" in boolean mode

↑のフラグはカスタマイズできるようにしたいなぁと思ったっきり
手付かずだったのでした。。。どんな風にカスタマイズできれば
MySQLになじむかしら。。。

-- 
須藤 功平 <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 メーリングリストの案内
Back to archive index