[groonga-dev,02447] Re: 「GROUP BY」条件をmroonga_command()で再現する方法

Back to archive index

Kouhei Sutou kou****@clear*****
2014年 6月 26日 (木) 11:06:48 JST


須藤です。

In <20140****@clear*****>
  "[groonga-dev,02444] Re: 「GROUP BY」条件をmroonga_command()で再現する方法" on Tue, 24 Jun 2014 15:02:17 +0900 (JST),
  Kouhei Sutou <kou****@clear*****> wrote:

>> Mroongaストレージエンジンからのmroonga_command()による全文検索を勉強中です。
>> 今は、過去に「GROUP BY」を使って実装していた処理を、Groongaコマンドに移し替えようとして四苦八苦しています。
>> 具体的には、たとえば以下のような処理を行いたいのですが、Groongaの--drilldownなり、他のオプションなりで実現できるでしょうか?
> 
> SET NAMES utf8;
> 
> CREATE TABLE t (
>   id int primary key auto_increment,
>   name varchar(255),
>   kana varchar(255)
> ) ENGINE = Mroonga DEFAULT CHARSET = utf8;
> 
> INSERT INTO t (name, kana) VALUES ("トム", "とむ");
> INSERT INTO t (name, kana) VALUES ("ジェリー", "じぇりー");
> INSERT INTO t (name, kana) VALUES ("十夢", "とむ");
> INSERT INTO t (name, kana) VALUES ("ミッキー", "みっきー");
> INSERT INTO t (name, kana) VALUES ("トム", "とむ");
> 
> というスキーマとデータで
> 
> SELECT *, count(id) AS c FROM t GROUP BY name ORDER BY kana ASC LIMIT 10;
> 
> 相当のことをmroonga_commandで実現できるか?ということですね!
> 
> ちょっと試してみたのですが、できませんでした。。。
> 
> 本当は
> 
> SELECT mroonga_command("select t --limit 0 --drilldown_limit 10 --drilldown_offset 0 --drilldown_output_columns _key,id,kana,_nsubrecs --drilldown name --drilldown_sortby kana") AS result;
> 
> ポイントは--drilldown_sortbyで、整形するとこんな感じ:
> 
>   select t
>     --limit 0
>     --drilldown_limit 10
>     --drilldown_offset 0
>     --drilldown_output_columns _key,id,kana,_nsubrecs
>     --drilldown name
>     --drilldown_sortby kana
> 
> で動いて欲しいところなんですが、今の実装だ
> と--drilldown_sortbyに実カラムの指定をサポートしていませんで
> した。(_nsubrecsなど擬似カラムは指定できる。)

すみません。これ、ウソでした。動いて欲しいところではなかった
です。これだと、グループ化したうち、どのレコードのkanaの値を
使うの?問題が発生するのでスジがよくなかったです。

> INSERT INTO t (name, kana) VALUES ("トム", "とむ");
> INSERT INTO t (name, kana) VALUES ("トム", "とむ");

というように2回「トム」→「とむ」を入れていますが、

INSERT INTO t (name, kana) VALUES ("トム", "とむ");
INSERT INTO t (name, kana) VALUES ("トム", "トム");

とか、kanaの値が違うと問題になります。なので、この場合は、

CREATE TABLE names (
  name varchar(255) PRIMARY KEY,
  kana varchar(255)
) ENGINE = Mroonga DEFAULT CHARSET = utf8;

CREATE TABLE t (
  id int primary key auto_increment,
  name varchar(255) COMMENT 'type "names"'
) ENGINE = Mroonga DEFAULT CHARSET = utf8;

というように正規化してください。で、こんな風にデータをいれて、

INSERT INTO names (name, kana) VALUES ("トム", "とむ");
INSERT INTO names (name, kana) VALUES ("ジェリー", "じぇりー");
INSERT INTO names (name, kana) VALUES ("十夢", "とむ");
INSERT INTO names (name, kana) VALUES ("ミッキー", "みっきー");

INSERT INTO t (name) VALUES ("トム");
INSERT INTO t (name) VALUES ("ジェリー");
INSERT INTO t (name) VALUES ("十夢");
INSERT INTO t (name) VALUES ("ミッキー");
INSERT INTO t (name) VALUES ("トム");

JOINしてください。

SELECT *, count(id) AS c FROM t
  INNER JOIN names ON t.name = names.name
  GROUP BY t.name
  ORDER BY names.kana ASC
  LIMIT 10;

これならnameのkanaは必ず一意に決まるのでどのレコードを使うの
問題は発生しません。

そして、このスキーマならGroongaでも動きます。

SELECT mroonga_command("select t --limit 0 --drilldown name --drilldown_limit 10 --drilldown_output_columns _key,id,kana,_nsubrecs --drilldown_sortby kana") AS result;

整形するとこうです。

  select t
    --limit 0
    --drilldown name
    --drilldown_limit 10
    --drilldown_output_columns _key,id,kana,_nsubrecs
    --drilldown_sortby kana


ということで、テーブルを正規化してください!が回答になります!

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

Groongaサポート:
  http://groonga.org/ja/support/
パッチ採用:
  http://www.clear-code.com/recruitment/
コードリーダー育成支援:
  http://www.clear-code.com/services/code-reader/




groonga-dev メーリングリストの案内
Back to archive index