Kouhei Sutou
kou****@clear*****
2015年 5月 8日 (金) 21:59:06 JST
須藤です。 In <CA+Tq****@mail*****> "[groonga-dev,03209] selectとin_valuesの制限事項について" on Fri, 8 May 2015 15:03:00 +0900, Hiroyuki Sato <hiroy****@gmail*****> wrote: > 1, 質問事項 > (1) selectの文字列の長さ上限 > selectの文字列の長さに上限はありますか? ありません。 リソース(メモリー)が許す限り長くできます。 ただし、文字列の長さの上限よりも前に↓のような他の上限に達す ると思います。 > (2) in_values(taget,value,value)のvalueの数の上限値 126個です。 メモ: GRN_SCAN_INFO_MAX_N_ARGSが128で0番目はprocedureオブジェ クトになって、1番目はカラム(のインデックス)になるので、残 りの126が第2引数以降に使える数の限界。 TODO: ドキュメントに書いておく。 > (3) in_valuesを使って全文検索のキーワードは指定できるか? できません。 > 例えばチュートリアル: 4.10のCommentsテーブルの下記クエリを > in_valuesに変えることは可能でしょうか? > > select --table Comments \ > --query 'comment:@NY OR comment:@tried' \ > --output_columns _key,comment > > 次のようにしたら結果が0になってしまいました。 > select --table Comments \ > --filter 'in_values(comment,"@NY","@tried")' \ > --output_columns comment in_valuesに変えることはできないのですが、--match_columnsに変え ることはできます。--match_columnsを使うとこうなります。 select --table Comments \ --match_columns 'comment' \ --query 'NY OR tried' \ --output_columns _key,comment > (4) 下記案1以外の方法 > 下記案1以外の方法で良い方法はございますでしょうか? 後述するように、あります。 > mroongaを使う等でも結構です。 今回のように込み入ったことをやるときは、Mroongaを使っていて もGroongaの機能を使うことになるんですよねぇ。 > 2, やりたいこと > (1), 用語 > (1-1) ユーザ: システムを利用する人 > (1-2) キーワード: ユーザが興味を持っているキーワード > 例) Groonga, rroonga, mysql等 > (1-3) 記事 > www.itmedia.co.jpなどに掲載される記事 > > (2) やりたいこと > (2-1) ある記事Aに興味を持っているユーザを抽出する。 > (2-2) 記事Aに興味を持っているかどうかは、各ユーザが持っている > キーワードが記事内に含まれているかを確認する。 > > (3) 実現案1 > (3-1) 実現方法 > ・記事テーブル(Articles)を作って全文検索をできるようにする > ・selectでユーザ毎にキーワードを指定して全文検索をする > > select --table Articles \ > --query 'text:キーワード1 OR text:キーワード2 OR ...' \ > --output_columns _key,comment > > (3-3) 課題・懸念点 > (a) in_values等を使ってもっと楽に検索条件を指定したい > > (b) キーワードの数多いと、文字列の上限に達してしまうのではないか? > > (c) できれば、なるべく少ない回数で、結果を抽出したい。 > キーワードをユーザのベクターカラムに格納して、SQLのジョインの > ようなことをしたい Groongaのクエリー(select)を考えるときのポイントは「どのテー ブルのデータを入手したいか」を最初に考えることです。今回は > (2-1) ある記事Aに興味を持っているユーザを抽出する。 なので、最終的なselectは「select --table Users ...」という形 になります。あとは、この形になるように逆算していきます。 > (2-2) 記事Aに興味を持っているかどうかは、各ユーザが持っている > キーワードが記事内に含まれているかを確認する。 なので、ユーザーを特定するには「記事内に含まれているキーワー ド」で検索する必要があります。 ここで、 ユーザー→キーワード→記事 ではなく 記事→キーワード→ユーザー という順に考え方を変えていることに注目してください。 ということで、最終的にはこんな感じになるはずです。 select --table Users \ --match_columns keywords \ --query '記事内に含まれているキーワード1 OR 記事内に含まれているキーワード2 OR ...' \ ... あとは、「記事内に含まれているキーワード」を抽出できればよい です。実は、それを実現する機能があります。 単語抽出演算子: http://groonga.org/ja/docs/reference/grn_expr/script_syntax.html#term-extract-operator ということで、↓で「記事内に含まれているキーワード」を抽出で きます。 select --table Keywords \ --filter '_key *T "記事の内容"' (「記事の内容」を直接書くんじゃなくて 「Articles[key].content」とかで参照できるようにしたほうがよ さそうですね。) 「記事の内容」を取得するために次のselectを実行する必要があり ます。 select --table Articles \ --filter '_key == "XXX"' \ --output_columns content 具体的なスキーマとデータとselectは次の通りです。 --- table_create Articles TABLE_HASH_KEY ShortText column_create Articles content COLUMN_SCALAR Text table_create Keywords TABLE_PAT_KEY ShortText \ --normalizer NormalizerAuto # 表示するときは正規化しない状態で表示したいならあると便利 # 例: 「groonga」ではなく「Groonga」と表示したい # column_create Keywords label COLUMN_SCALAR ShortText table_create Users TABLE_HASH_KEY ShortText column_create Users keywords COLUMN_VECTOR Keywords column_create Keywords users_keywords COLUMN_INDEX Users keywords load --table Articles [ {"_key": "article1", "content": "Groonga and Mroonga are good!"}, {"_key": "article2", "content": "MySQL and PostgreSQL are good!"}, {"_key": "article3", "content": "Groonga + MySQL = Mroonga!"} ] load --table Users [ {"_key": "user1", "keywords": ["Groonga", "MySQL"]}, {"_key": "user2", "keywords": ["MySQL"]}, {"_key": "user3", "keywords": ["Mroonga"]} {"_key": "user4", "keywords": ["PostgreSQL"]} ] select \ --table Articles \ --filter '_key == "article1"' \ --output_columns content # -> "Groonga and Mroonga are good!" select \ --table Keywords \ --filter '_key *T "Groonga and Mroonga are good!"' \ --output_columns _key # -> ["groonga", "mroonga"] select \ --table Users \ --match_columns keywords \ --query 'groonga OR mroonga' # -> [["user1", ["groonga", "mysql"]], ["user3", ["mroonga"]]] --- -- 須藤 功平 <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/