Kouhei Sutou
kou****@clear*****
2009年 4月 21日 (火) 17:06:43 JST
須藤です。 groongaっぽいインデックスの使い方について教えて下さい。 # あまり理解できていなかったようです。。。 こんなテーブルを考えています。 <users>: GRN_OBJ_NO_KEY カラム: name: <shorttext> <bookmarks>: GRN_OBJ_NO_KEY カラム: uri: <shorttext> comment: <shorttext> user: <users> # <users>テーブルを参照 user-vector: <index>|GRN_OBJ_COLUMN_VECTOR # <bookmarks>.userと同じものをvectorでいれる <index>: GRN_OBJ_HASH_KEY カラム: comment: <bookmarks>: GRN_COLUMN_INDEX # <bookmarks>.comment用インデックス user: <bookmarks>: GRN_COLUMN_INDEX # <bookmarks>.user用インデックス <index>.commentは特定のコメントを含むブックマーク一覧を取得 するためのものです。 <index>.userは特定のユーザのブックマーク一覧を取得するための ものです。 # <index>.commentのGRN_INFO_SOURCEには<bookmarks>.commentを # 指定していて、 # <index>.userのGRN_INFO_SOURCEには<bookmarks>.userを指定し # ているとすると、 <index>.commentのように値(range)が<text>系のカラムのインデッ クスの場合は、 grn_obj_set_value(): <bookmarks>.commentの値にGRN_BULKを設定 で、インデックスが作成され、 grn_obj_search(): <index>.commentからGRN_BULKにした検索ワー ドで検索 で、インデックスを利用した検索ができると思います。 同じように、<index>.userのように値がテーブルオブジェクトのカ ラムもインデックスの作成とインデックスを利用した検索をするの がgroongaっぽいのかと思います。 以下のようにすると実現できているっぽいのですが、とても面倒な ので、もっとうまい方法があるのではないかと思っています。 # GRN_INFO_SOURCEは利用できない? インデックスの作成: grn_obj_set_value(): - <bookmarks>.userの値にGRN_BULKで、<users>レコードのIDを設定 - <bookmarks>.user-vectorの値にGRN_VECTORで、<users>レコー ドのIDを設定 - <index>.userの値にGRN_UVECTORで、<bookmarks>.user-vector が<index>に追加したレコードのIDを設定 イメージコード: <bookmarks>.user grn_obj *value; grn_id user_id; void *user_id_p; user_id_p = &user_id; value = grn_obj_open(context, GRN_BULK, 0, 0); grn_bulk_write(context, value, user_id_p, sizeof(grn_id)); grn_obj_set_value(context, <bookmarks>.user, bookmark_id, value, GRN_OBJ_SET); イメージコード: <bookmarks>.user-vector grn_obj *value; grn_id user_id; void *user_id_p; user_id_p = &user_id; value = grn_obj_open(context, GRN_VECTOR, 0, 0); grn_vector_add_element(context, value, user_id_p, sizeof(grn_id), 0, 0); grn_obj_set_value(context, <bookmarks>.user-vector, bookmark_id, value, GRN_OBJ_SET); イメージコード: <index>.user grn_obj *value; grn_id token_id; void *token_id_p; user_id_p = &user_id; token_id = grn_table_lookup(context, <index>, user_id_p, sizeof(grn_id), NULL); token_id_p = &token_id; value = grn_obj_open(context, GRN_UVECTOR, 0, 0); grn_bulk_write(context, value, token_id_p, sizeof(grn_id)); grn_column_index_update(context, <index>.user, bookmark_id, 1, NULL, value); 検索: grn_obj_search(): <index>.userからGRN_BULKで<users>レコー ドのIDを指定して検索(レコードIDが1なら"\001\000\000\000") →見つかっているっぽい。 検索文字列がトークナイザーで壊されちゃいそうだけど大丈夫? インデックスの更新が面倒なので、別の方法があるのではないかと 思っています。こういうときはhookを指定してうまい具合にやるも のなのでしょうか? もしよかったら、groongaらしいやりかたを教えてもらえないでしょ うか?