[groonga-dev,00154] grn_expr_parse()またはGRN_OP_EXPR_EXECが欲しい

Back to archive index

Kouhei Sutou kou****@clear*****
2009年 8月 9日 (日) 22:48:22 JST


須藤です。

grn_expr_create_from_str()は文字列でg式が作れて便利ですが、
それに加えてgrn_expr_append_op()などで付加的な条件も指定でき
るともっと便利です。

例えば、一週間以内に登録された文書の中から「groonga」または
「Senna」にマッチする文書を探したい場合、groonga/Sennaを探す
部分は"groonga OR senna"と文字列で書くと便利ですが、一週間以
内という部分はTime.now - 60 * 60 * 24 * 7とプログラムで書け
ると便利です。(Rubyでごめんなさい)

ということで、

  (1) 既存のgrn_exprに文字列で条件を追加できるgrn_expr_parse()
  (2) grn_expr_create_from_str()で作成したgrn_exprを別の
      grn_exprの中で実行するGRN_OP_EXPR_EXEC

のどちらかがあると、上記を実現できそうな気がしています。

とりあえず、(1)用のパッチをつけます。
(grn_expr_create_from_str()と重複している部分が多いので、本
当は共通化したいところです。)

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

diff --git a/groonga.h b/groonga.h
index e1fbb48..a567ed6 100644
--- a/groonga.h
+++ b/groonga.h
@@ -1808,6 +1808,9 @@ GRN_API grn_obj *grn_expr_create_from_str(grn_ctx *ctx,
                                           const char *name, unsigned name_size,
                                           const char *str, unsigned str_size,
                                           grn_obj *table, grn_obj *default_column);
+GRN_API grn_rc grn_expr_parse(grn_ctx *ctx, grn_obj *expression,
+                              const char *str, unsigned str_size,
+                              grn_obj *table, grn_obj *default_column);
 
 GRN_API grn_table_sort_key *grn_table_sort_key_from_str(grn_ctx *ctx,
                                                         const char *str, unsigned str_size,
diff --git a/lib/db.c b/lib/db.c
index 02bc179..d16aa17 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -7510,6 +7510,40 @@ exit :
   return efsi.e;
 }
 
+grn_rc
+grn_expr_parse(grn_ctx *ctx, grn_obj *expression,
+               const char *str, unsigned str_size,
+               grn_obj *table, grn_obj *default_column)
+{
+  efs_info efsi;
+  GRN_TEXT_INIT(&efsi.buf, 0);
+  efsi.e = expression;
+  efsi.str = str;
+  efsi.v = grn_expr_get_var_by_offset(ctx, efsi.e, 0);
+  efsi.cur = str;
+  efsi.str_end = str + str_size;
+  efsi.table = table;
+  efsi.default_column = default_column;
+  efsi.default_op = GRN_OP_AND;
+  efsi.escalation_threshold = GROONGA_DEFAULT_QUERY_ESCALATION_THRESHOLD;
+  efsi.escalation_decaystep = DEFAULT_DECAYSTEP;
+  efsi.weight_offset = 0;
+  efsi.opt.weight_vector = NULL;
+  efsi.weight_set = NULL;
+  get_pragma(ctx, &efsi);
+  if (get_expr(ctx, &efsi, default_column, GRN_OP_MATCH)) {
+    goto exit;
+  }
+  grn_expr_compile(ctx, efsi.e);
+  efsi.opt.vector_size = DEFAULT_WEIGHT_VECTOR_SIZE;
+  efsi.opt.func = efsi.weight_set ? section_weight_cb : NULL;
+  efsi.opt.func_arg = efsi.weight_set;
+  efsi.snip_conds = NULL;
+exit :
+  GRN_OBJ_FIN(ctx, &efsi.buf);
+  return ctx->rc;
+}
+
 grn_table_sort_key *
 grn_table_sort_key_from_str(grn_ctx *ctx, const char *str, unsigned str_size,
                             grn_obj *table, unsigned *nkeys)




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