[Groonga-commit] groonga/groonga [master] Supported edit_distance on suggest command.

Back to archive index

null+****@clear***** null+****@clear*****
2010年 8月 24日 (火) 19:41:20 JST


Tasuku SUENAGA a.k.a. gunyarakun	2010-08-24 10:41:20 +0000 (Tue, 24 Aug 2010)

  New Revision: 65b79f0932bc48297fac8147a181916a23a7a4cc

  Log:
    Supported edit_distance on suggest command.

  Modified files:
    modules/suggest/suggest.c

  Modified: modules/suggest/suggest.c (+52 -5)
===================================================================
--- modules/suggest/suggest.c    2010-08-24 09:32:49 +0000 (ea20464)
+++ modules/suggest/suggest.c    2010-08-24 10:41:20 +0000 (39934d0)
@@ -57,6 +57,7 @@ command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_dat
                   grn_ii_posting *p;
                   while ((p = grn_ii_cursor_next(ctx, icur))) {
                     grn_hash_add(ctx, (grn_hash *)res, &p->rid, sizeof(grn_id), NULL, NULL);
+                    /* FIXME: execute _score = score */
                   }
                   grn_ii_cursor_close(ctx, icur);
                 } else {
@@ -78,26 +79,72 @@ command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_dat
           optarg.similarity_threshold = 1048576;
 
           grn_ii_select(ctx, (grn_ii *)grn_ctx_get(ctx, CONST_STR_LEN("SuggestBigram.suggest_key")),
-                        GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)), (grn_hash *)res, GRN_OP_OR, &optarg);
+                        GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
+                        (grn_hash *)res, GRN_OP_OR, &optarg);
+          {
+            /* exec _score = edit_distance(_key, "query string") for all records */
+            grn_obj *var;
+            grn_obj *expr;
+
+            GRN_EXPR_CREATE_FOR_QUERY(ctx, res, expr, var);
+            if (expr) {
+              grn_table_cursor *tc;
+
+              grn_expr_append_obj(ctx, expr,
+                                  grn_obj_column(ctx, res, CONST_STR_LEN("_score")),
+                                  GRN_OP_GET_VALUE, 1);
+              grn_expr_append_obj(ctx, expr,
+                                  grn_ctx_get(ctx, CONST_STR_LEN("edit_distance")),
+                                  GRN_OP_PUSH, 1);
+              grn_expr_append_obj(ctx, expr,
+                                  grn_obj_column(ctx, res, CONST_STR_LEN("_key")),
+                                  GRN_OP_GET_VALUE, 1);
+              grn_expr_append_const(ctx, expr, VAR(2), GRN_OP_PUSH, 1);
+              grn_expr_append_op(ctx, expr, GRN_OP_CALL, 2);
+              grn_expr_append_op(ctx, expr, GRN_OP_ASSIGN, 2);
+
+              if ((tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0, -1, 0))) {
+                while (!grn_table_cursor_next_o(ctx, tc, var)) {
+                  grn_expr_exec(ctx, expr, 0);
+                }
+                grn_table_cursor_close(ctx, tc);
+              }
+              grn_expr_close(ctx, expr);
+            } else {
+              ERR(GRN_UNKNOWN_ERROR, "error on building expr. for calicurating edit distance");
+            }
+          }
 #endif
           /* sort */
           {
             uint32_t nkeys;
+            grn_obj *score_col;
             grn_table_sort_key *keys;
-            if ((keys = grn_table_sort_key_from_str(ctx, CONST_STR_LEN("-score"), res, &nkeys))) {
+            score_col = grn_obj_column(ctx, res, CONST_STR_LEN("_score"));
+            /* FIXME: use grn_table_sort instead */
+            if ((keys = grn_table_sort_key_from_str(ctx, CONST_STR_LEN("-_score"), res, &nkeys))) {
               grn_table_cursor *scur;
               /* TODO: support offset limit */
               grn_table_sort(ctx, res, 0, grn_table_size(ctx, res), sorted, keys, nkeys);
-              GRN_OUTPUT_ARRAY_OPEN("RESULT", -1);
+              GRN_OUTPUT_ARRAY_OPEN("RESULTS", -1);
               if ((scur = grn_table_cursor_open(ctx, sorted, NULL, 0, NULL, 0, 0, -1, 0))) {
                 grn_id id;
                 while ((id = grn_table_cursor_next(ctx, scur))) {
+                  grn_id res_id;
                   unsigned int key_len;
                   char key[GRN_TABLE_MAX_KEY_SIZE];
-                  grn_table_get_key(ctx, sorted, id, &id, sizeof(grn_id));
-                  grn_table_get_key(ctx, res, id, &id, sizeof(grn_id));
+                  grn_obj score_val;
+
+                  GRN_OUTPUT_ARRAY_OPEN("RESULT", 2);
+                  grn_table_get_key(ctx, sorted, id, &res_id, sizeof(grn_id));
+                  grn_table_get_key(ctx, res, res_id, &id, sizeof(grn_id));
                   key_len = grn_table_get_key(ctx, table, id, key, GRN_TABLE_MAX_KEY_SIZE);
                   GRN_OUTPUT_STR(key, key_len);
+
+                  GRN_INT32_INIT(&score_val, 0);
+                  grn_obj_get_value(ctx, score_col, res_id, &score_val);
+                  GRN_OUTPUT_INT32(GRN_INT32_VALUE(&score_val));
+                  GRN_OUTPUT_ARRAY_CLOSE();
                 }
                 grn_table_cursor_close(ctx, scur);
               } else {




Groonga-commit メーリングリストの案内
Back to archive index