null+****@clear*****
null+****@clear*****
2010年 8月 30日 (月) 16:39:19 JST
Daijiro MORI 2010-08-30 07:39:19 +0000 (Mon, 30 Aug 2010)
New Revision: 9f7e1bcb13c8fcc9018fb181fb78fe23c96935db
Log:
Enhanced suggest command.
Modified files:
modules/suggest/suggest.c
Modified: modules/suggest/suggest.c (+62 -9)
===================================================================
--- modules/suggest/suggest.c 2010-08-30 06:21:47 +0000 (9508623)
+++ modules/suggest/suggest.c 2010-08-30 07:39:19 +0000 (48d02c5)
@@ -106,8 +106,8 @@ cooccur_search(grn_ctx *ctx, grn_obj *table, grn_id id, grn_obj *res, int query_
ifreq = GRN_INT32_VALUE(&item_freq);
if (pfreq && ifreq) {
grn_rset_recinfo *ri;
- uint32_t score = 1000/pfreq;
- if (max_score < pfreq) { max_score = pfreq; }
+ uint32_t score = pfreq;
+ if (max_score < score) { max_score = score; }
/* put any formula if desired */
if (grn_hash_add(ctx, (grn_hash *)res,
&post_id, sizeof(grn_id), (void **)&ri, NULL)) {
@@ -134,7 +134,7 @@ output(grn_ctx *ctx, grn_obj *table, grn_obj *res, int limit, grn_id tid)
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))) {
+ 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, limit + 1, sorted, keys, nkeys);
@@ -179,6 +179,11 @@ static void
complete(grn_ctx *ctx, grn_obj *table, grn_obj *col, grn_obj *query)
{
grn_obj *res;
+ grn_obj *items_freq = grn_obj_column(ctx, table, CONST_STR_LEN("freq"));
+ grn_obj *items_boost = grn_obj_column(ctx, table, CONST_STR_LEN("boost"));
+ grn_obj item_freq, item_boost;
+ GRN_INT32_INIT(&item_freq, 0);
+ GRN_INT32_INIT(&item_boost, 0);
if ((res = grn_table_create(ctx, NULL, 0, NULL,
GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL))) {
grn_id tid = grn_table_get(ctx, table, TEXT_VALUE_LEN(query));
@@ -200,8 +205,16 @@ complete(grn_ctx *ctx, grn_obj *table, grn_obj *col, grn_obj *query)
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 */
+ uint32_t score;
+ grn_rset_recinfo *ri;
+ grn_hash_add(ctx, (grn_hash *)res,
+ &p->rid, sizeof(grn_id), (void **)&ri, NULL);
+ GRN_BULK_REWIND(&item_freq);
+ GRN_BULK_REWIND(&item_boost);
+ grn_obj_get_value(ctx, items_freq, p->rid, &item_freq);
+ grn_obj_get_value(ctx, items_boost, p->rid, &item_boost);
+ score = GRN_INT32_VALUE(&item_freq) + GRN_INT32_VALUE(&item_boost);
+ ri->score += score;
}
grn_ii_cursor_close(ctx, icur);
}
@@ -221,7 +234,15 @@ complete(grn_ctx *ctx, grn_obj *table, grn_obj *col, grn_obj *query)
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);
+ uint32_t score;
+ grn_rset_recinfo *ri;
+ grn_hash_add(ctx, (grn_hash *)res, &id, sizeof(grn_id), (void **)&ri, NULL);
+ GRN_BULK_REWIND(&item_freq);
+ GRN_BULK_REWIND(&item_boost);
+ grn_obj_get_value(ctx, items_freq, id, &item_freq);
+ grn_obj_get_value(ctx, items_boost, id, &item_boost);
+ score = GRN_INT32_VALUE(&item_freq) + GRN_INT32_VALUE(&item_boost);
+ ri->score += score;
}
grn_table_cursor_close(ctx, cur);
}
@@ -231,12 +252,19 @@ complete(grn_ctx *ctx, grn_obj *table, grn_obj *col, grn_obj *query)
} else {
ERR(GRN_UNKNOWN_ERROR, "cannot create temporary table.");
}
+ GRN_OBJ_FIN(ctx, &item_boost);
+ GRN_OBJ_FIN(ctx, &item_freq);
}
static void
correct(grn_ctx *ctx, grn_obj *table, grn_obj *query)
{
grn_obj *res;
+ grn_obj *items_freq = grn_obj_column(ctx, table, CONST_STR_LEN("freq"));
+ grn_obj *items_boost = grn_obj_column(ctx, table, CONST_STR_LEN("boost"));
+ grn_obj item_freq, item_boost;
+ GRN_INT32_INIT(&item_freq, 0);
+ GRN_INT32_INIT(&item_boost, 0);
if ((res = grn_table_create(ctx, NULL, 0, NULL,
GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL))) {
grn_id tid = grn_table_get(ctx, table, TEXT_VALUE_LEN(query));
@@ -251,11 +279,34 @@ correct(grn_ctx *ctx, grn_obj *table, grn_obj *query)
optarg.mode = GRN_OP_SIMILAR;
optarg.similarity_threshold = 0;
grn_ii_select(ctx, (grn_ii *)index, TEXT_VALUE_LEN(query),
- (grn_hash *)res, GRN_OP_ADJUST, &optarg);
+ (grn_hash *)res, GRN_OP_OR, &optarg);
grn_obj_unlink(ctx, index);
LAP("similar", grn_table_size(ctx, res));
{
- /* exec _score = edit_distance(_key, "query string") for all records */
+ grn_hash_cursor *hc = grn_hash_cursor_open(ctx, (grn_hash *)res, NULL,
+ 0, NULL, 0, 0, -1, 0);
+ if (hc) {
+ uint32_t score;
+ grn_id *rp;
+ grn_rset_recinfo *ri;
+ while (grn_hash_cursor_next(ctx, hc)) {
+ if (grn_hash_cursor_get_key_value(ctx, hc, (void **)(&rp), NULL,
+ (void **)(&ri))) {
+ GRN_BULK_REWIND(&item_freq);
+ GRN_BULK_REWIND(&item_boost);
+ grn_obj_get_value(ctx, items_freq, *rp, &item_freq);
+ grn_obj_get_value(ctx, items_boost, *rp, &item_boost);
+ score = GRN_INT32_VALUE(&item_freq) + GRN_INT32_VALUE(&item_boost);
+ ri->score += score;
+ if (score < 100) { grn_hash_cursor_delete(ctx, hc, NULL); }
+ }
+ }
+ grn_hash_cursor_close(ctx, hc);
+ }
+ }
+ LAP("filter", grn_table_size(ctx, res));
+ {
+ /* exec _score -= edit_distance(_key, "query string") for all records */
grn_obj *var;
grn_obj *expr;
@@ -275,7 +326,7 @@ correct(grn_ctx *ctx, grn_obj *table, grn_obj *query)
GRN_OP_GET_VALUE, 1);
grn_expr_append_const(ctx, expr, query, GRN_OP_PUSH, 1);
grn_expr_append_op(ctx, expr, GRN_OP_CALL, 2);
- grn_expr_append_op(ctx, expr, GRN_OP_ASSIGN, 2);
+ grn_expr_append_op(ctx, expr, GRN_OP_MINUS_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)) {
@@ -300,6 +351,8 @@ correct(grn_ctx *ctx, grn_obj *table, grn_obj *query)
} else {
ERR(GRN_UNKNOWN_ERROR, "cannot create temporary table.");
}
+ GRN_OBJ_FIN(ctx, &item_boost);
+ GRN_OBJ_FIN(ctx, &item_freq);
}
static void