null+****@clear*****
null+****@clear*****
2010年 8月 26日 (木) 18:14:15 JST
Tasuku SUENAGA a.k.a. gunyarakun 2010-08-26 09:14:15 +0000 (Thu, 26 Aug 2010)
New Revision: f6f3bf62a90eb8d69556bbfe8b7d785441b92c3e
Log:
Now command suggest supports types parameter.
Modified files:
doc/ja/source/commands/suggest.txt
modules/suggest/suggest.c
Modified: doc/ja/source/commands/suggest.txt (+2 -2)
===================================================================
--- doc/ja/source/commands/suggest.txt 2010-08-26 09:00:29 +0000 (6202fda)
+++ doc/ja/source/commands/suggest.txt 2010-08-26 09:14:15 +0000 (846bd7b)
@@ -14,7 +14,7 @@ suggest - 指定したクエリに対する補完・修正・提案を行う。
----
::
- suggest type table column query
+ suggest types table column query
説明
----
@@ -26,7 +26,7 @@ suggestコマンドは、指定したクエリに対して補完・修正・提
引数
----
-``type``
+``types``
補完・修正・提案のいずれを行うかを、パイプ('|')で組み合わせたシンボル名で指定します(例: correct|suggest)
Modified: modules/suggest/suggest.c (+117 -83)
===================================================================
--- modules/suggest/suggest.c 2010-08-26 09:00:29 +0000 (56dc239)
+++ modules/suggest/suggest.c 2010-08-26 09:14:15 +0000 (17bbc31)
@@ -23,15 +23,43 @@
#define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
#define VAR GRN_PROC_GET_VAR_BY_OFFSET
+static int
+grn_parse_suggest_types(const char *nptr, const char *end)
+{
+ int types = 0;
+ while (nptr < end) {
+ if (*nptr == '|') {
+ nptr += 1;
+ continue;
+ }
+ if (!memcmp(nptr, CONST_STR_LEN("complete"))) {
+ types |= 1;
+ nptr += sizeof("complete") - 1;
+ }
+ if (!memcmp(nptr, CONST_STR_LEN("correct"))) {
+ types |= 2;
+ nptr += sizeof("correct") - 1;
+ }
+ if (!memcmp(nptr, CONST_STR_LEN("suggest"))) {
+ types |= 4;
+ nptr += sizeof("suggest") - 1;
+ }
+ }
+ return types;
+}
+
static grn_obj *
command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
+ int types;
grn_obj *table;
- if ((table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)),
- GRN_TEXT_LEN(VAR(0))))) {
+ types = grn_parse_suggest_types(GRN_TEXT_VALUE(VAR(0)), GRN_BULK_CURR(VAR(0)));
+
+ if ((table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(1)),
+ GRN_TEXT_LEN(VAR(1))))) {
grn_obj *col;
- if ((col = grn_obj_column(ctx, table, GRN_TEXT_VALUE(VAR(1)),
- GRN_TEXT_LEN(VAR(1))))) {
+ if ((col = grn_obj_column(ctx, table, GRN_TEXT_VALUE(VAR(2)),
+ GRN_TEXT_LEN(VAR(2))))) {
grn_obj *res;
if ((res = grn_table_create(ctx, NULL, 0, NULL,
GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL))) {
@@ -39,60 +67,62 @@ command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_dat
if ((sorted = grn_table_create(ctx, NULL, 0, NULL,
GRN_OBJ_TABLE_NO_KEY, NULL, res))) {
grn_str *norm;
- if ((norm = grn_str_open(ctx, GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
+ if ((norm = grn_str_open(ctx, GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
GRN_STR_NORMALIZE))) {
-#if 1
- /* RK search + prefix search */
- grn_obj *index;
- /* FIXME: support index selection */
- if (grn_column_index(ctx, col, GRN_OP_PREFIX,
- &index, 1, NULL)) {
- grn_table_cursor *cur;
- if ((cur = grn_table_cursor_open(ctx, grn_ctx_at(ctx, index->header.domain),
- norm->norm, norm->norm_blen,
- NULL, 0,
- 0, -1,
- GRN_CURSOR_PREFIX | GRN_CURSOR_RK))) {
- grn_id id;
- while ((id = grn_table_cursor_next(ctx, cur))) {
- grn_ii_cursor *icur;
- if ((icur = grn_ii_cursor_open(ctx, (grn_ii *)index, id,
- GRN_ID_NIL, GRN_ID_MAX, 1, 0))) {
- 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 */
+ if (types & 1) {
+ /* RK search + prefix search */
+ grn_obj *index;
+ /* FIXME: support index selection */
+ if (grn_column_index(ctx, col, GRN_OP_PREFIX,
+ &index, 1, NULL)) {
+ grn_table_cursor *cur;
+ if ((cur = grn_table_cursor_open(ctx, grn_ctx_at(ctx, index->header.domain),
+ norm->norm, norm->norm_blen,
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX | GRN_CURSOR_RK))) {
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx, cur))) {
+ grn_ii_cursor *icur;
+ if ((icur = grn_ii_cursor_open(ctx, (grn_ii *)index, id,
+ GRN_ID_NIL, GRN_ID_MAX, 1, 0))) {
+ 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);
}
- grn_ii_cursor_close(ctx, icur);
}
+ grn_table_cursor_close(ctx, cur);
+ } else {
+ ERR(GRN_UNKNOWN_ERROR, "cannot open cursor for pk.");
+ goto exit;
}
- grn_table_cursor_close(ctx, cur);
- } else {
- ERR(GRN_UNKNOWN_ERROR, "cannot open cursor for pk.");
- goto exit;
- }
- if ((cur = grn_table_cursor_open(ctx, table,
- GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
- NULL, 0, 0, -1, GRN_CURSOR_PREFIX))) {
- grn_id id;
- while ((id = grn_table_cursor_next(ctx, cur))) {
- grn_hash_add(ctx, (grn_hash *)res, &id, sizeof(grn_id), NULL, NULL);
+ if ((cur = grn_table_cursor_open(ctx, table,
+ GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
+ NULL, 0, 0, -1, GRN_CURSOR_PREFIX))) {
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx, cur))) {
+ grn_hash_add(ctx, (grn_hash *)res, &id, sizeof(grn_id), NULL, NULL);
+ }
+ grn_table_cursor_close(ctx, cur);
}
- grn_table_cursor_close(ctx, cur);
+ } else {
+ ERR(GRN_UNKNOWN_ERROR, "cannot find index for prefix search.");
}
- } else {
- ERR(GRN_UNKNOWN_ERROR, "cannot find index for prefix search.");
- goto exit;
+ grn_str_close(ctx, norm);
}
-#else
+ }
+ if (types & 2) {
grn_select_optarg optarg;
memset(&optarg, 0, sizeof(grn_select_optarg));
optarg.mode = GRN_OP_SIMILAR;
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_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
(grn_hash *)res, GRN_OP_OR, &optarg);
{
/* exec _score = edit_distance(_key, "query string") for all records */
@@ -128,51 +158,53 @@ command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_dat
goto exit;
}
}
-#endif
- /* sort */
- {
- uint32_t nkeys;
- grn_obj *score_col;
- grn_table_sort_key *keys;
- 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("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_obj score_val;
+ }
+ if (types & 4) {
+ }
+ if (ctx->rc) { goto exit; }
- 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);
+ /* sort */
+ {
+ uint32_t nkeys;
+ grn_obj *score_col;
+ grn_table_sort_key *keys;
+ 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("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_obj score_val;
- 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 {
- ERR(GRN_UNKNOWN_ERROR, "cannot open sorted cursor.");
+ 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_OUTPUT_ARRAY_CLOSE();
- grn_table_sort_key_close(ctx, keys, nkeys);
+ grn_table_cursor_close(ctx, scur);
} else {
- ERR(GRN_UNKNOWN_ERROR, "cannot sort.");
+ ERR(GRN_UNKNOWN_ERROR, "cannot open sorted cursor.");
}
+ GRN_OUTPUT_ARRAY_CLOSE();
+ grn_table_sort_key_close(ctx, keys, nkeys);
+ } else {
+ ERR(GRN_UNKNOWN_ERROR, "cannot sort.");
}
-exit:
- grn_str_close(ctx, norm);
}
+exit:
grn_obj_close(ctx, sorted);
} else {
ERR(GRN_UNKNOWN_ERROR, "cannot create temporary sort table.");
@@ -301,6 +333,7 @@ grn_module_register_suggest(grn_ctx *ctx)
{
/* TODO: offset/limit */
grn_expr_var vars[] = {
+ {CONST_STR_LEN("types")},
{CONST_STR_LEN("table")},
{CONST_STR_LEN("column")},
{CONST_STR_LEN("query")}
@@ -308,8 +341,9 @@ grn_module_register_suggest(grn_ctx *ctx)
GRN_TEXT_INIT(&vars[0].value, 0);
GRN_TEXT_INIT(&vars[1].value, 0);
GRN_TEXT_INIT(&vars[2].value, 0);
+ GRN_TEXT_INIT(&vars[3].value, 0);
grn_proc_create(ctx, CONST_STR_LEN("suggest"), GRN_PROC_COMMAND,
- command_suggest, NULL, NULL, 3, vars);
+ command_suggest, NULL, NULL, 4, vars);
grn_proc_create(ctx, CONST_STR_LEN("suggest_preparer"), GRN_PROC_FUNCTION,
func_suggest_preparer, NULL, NULL, 0, NULL);