三日で書くgroonga関数

19
三日で作る Groonga 関数 hotpepsi@twitter

Upload: firewood

Post on 13-Jul-2015

1.860 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: 三日で書くGroonga関数

三日で作る Groonga 関数

hotpepsi@twitter

Page 2: 三日で書くGroonga関数

Agenda filter で呼べる関数を自作する ただし三日くらいで

Page 3: 三日で書くGroonga関数

背景 しょぼいサーバでスループットを上げ

たい 更新中も検索を止めたくない

検索されるものは全部 Groonga につっこむ

Page 4: 三日で書くGroonga関数

処理したい内容 親子関係を持つテーブルがある 親と子の個数の比は 1:n ある条件で子テーブルを検索し、合致

する親テーブルを取得したい

具体的には : 商品 (1) : 在庫・価格 (n)

Page 5: 三日で書くGroonga関数

SQL の場合 子テーブルに親テーブルを JOIN

検索結果を親のキーで DISTINCT

Groonga の場合、素直にはできない ※ ドリルダウンすれば 2 度引きで可能

Page 6: 三日で書くGroonga関数

Groonga の場合 子テーブルで検索する

重複するキーを filter で捨てる

filter で使える関数を自作する必要がある

Page 7: 三日で書くGroonga関数

自作する関数の仕様 引数として親のキー( _key )をとる 格納済かどうかを返す

Int32 distinct(ShortText parent_key)

Page 8: 三日で書くGroonga関数

雛形 test/unit/fix/fixtures/modules/string.c に

ある str_len を参考にする 自作の関数を登録する :grn_proc_create

grn_proc_create(ctx, "str_len", strlen("str_len"), GRN_PROC_FUNCTION, func_str_len, NULL, NULL, 0, NULL);

Page 9: 三日で書くGroonga関数

とりあえず版 登録 proc.c...grn_proc_create(ctx, "distinct", 8, GRN_PROC_FUNCTION, func_distinct, NULL, NULL, 0, NULL);...

Page 10: 三日で書くGroonga関数

とりあえず版 関数 proc.cstatic grn_obj *func_distinct(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { int result = 0; grn_obj *obj; if (nargs == 1) { grn_obj *item_key = args[0]; result = _distinct(GRN_TEXT_VALUE(item_key), GRN_TEXT_LEN(item_key)); if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) { GRN_UINT32_SET(ctx, obj, result); } } return obj;}

Page 11: 三日で書くGroonga関数

とりあえず版 中身 distinct.cc#include <string>#include <set>

typedef std::set<std::string> Map;static Map _map; // 格納済キーの保存庫

extern "C" int _distinct(const char *name, size_t length) { std::string _key(name, length); // std::string に変換 Map::iterator it = _map.find(_key); // キーを探す if (it != _map.end()) return 0; // 格納済なら 0 を返す _map.insert(key); // 格納する return 1;}

Page 12: 三日で書くGroonga関数

適当にビルドしてみる lib/ に distinct.cc を追加して make

よくわからないエラー ../lib/.libs/libgroonga.so: undefined

reference to `__cxa_begin_catch‘

g++ 経由でリンクしないと駄目

Page 13: 三日で書くGroonga関数

正式なやり方 configure.ac に AC_PROG_CXX を追加 lib/Makefile.am の

libgroonga_la_SOURCES に distinct.ccを追加

autoreconf で configure を再生成

Page 14: 三日で書くGroonga関数

autoreconf への道 色々更新が必要

autoconf-2.67 automake-1.11.1 libtool-2.2.6b

激しく遠い道のりなので以下略

Page 15: 三日で書くGroonga関数

手抜き Makefile.in に追記

.SUFFIXES に .cc を追加 CCLD を gcc から g++ に変更 ビルドルールに .cc.o を追加

Page 16: 三日で書くGroonga関数

デモ 商品テーブル item

ShortText 型 description 3 件

在庫テーブル stock item 型 i Time 型 date Int32 型 price 9 件

Page 17: 三日で書くGroonga関数

distinct なし select --table stock --output_columns

i._key,price

→ i._key が重複する

Page 18: 三日で書くGroonga関数

distinct あり select --table stock --filter

"distinct(i._key)" --output_columns i._key,price

→ i._key が重複しない

Page 19: 三日で書くGroonga関数

end of file