/* * call-seq: * select(string, option=>value, ...) * select(string, recs, option=>value, ...) * select(string, recs, op, option=>value, ...) * * インデックスの検索。 * * 有効な option: * :mode [Integer] :: 次のいずれか。Senna::SEL_EXACT, Senna::SEL_PARTIAL, Senna::SEL_UNSPLIT, Senna::SEL_NEAR, Senna::SEL_SIMILAR, Senna::SEL_PREFIX, Senna::SEL_SUFFIX * :similarity_threshold [Integer] :: Senna API DOC 参照 * :max_interval [Integer] :: Senna API DOC 参照 * :weight_vector [Array of Integer] :: Senna API DOC 参照 * :vector_size [Integer] :: Senna API DOC 参照 * * === Argument * string [String] :: 検索する文字列 * recs [Senna::Records] :: 結果が反映されるレコード群。未指定時は空の Senna::Records が作成される。 * op [Integer] :: 次のいずれか。Senna::SEL_OR(default), Senna::SEL_AND, Senna::SEL_BUT, Senna::SEL_ADJUST * * === Return * Senna::Records :: recs と同じ。 */ static VALUE index_select(int argc, VALUE *argv, VALUE obj) { VALUE string; VALUE arg1, arg2, arg3; VALUE recs = Qnil; VALUE op = Qnil; VALUE optarg = Qnil; struct index_data *data; sen_records *_recs; sen_sel_operator _op; sen_select_optarg _optarg, *_optarg_p; sen_rc rc; int n; n = rb_scan_args(argc, argv, "13", &string, &arg1, &arg2, &arg3); Check_Type(string, T_STRING); switch (n) { case 1: break; case 2: if (TYPE(arg1) == T_HASH) optarg = arg1; else recs = arg1; break; case 3: recs = arg1; if (TYPE(arg2) == T_HASH) optarg = arg2; else op = arg2; break; case 4: recs = arg1; op = arg2; optarg = arg3; break; } if (NIL_P(recs)) { _recs = sen_records_open(sen_rec_document, sen_rec_none, 0); recs = Data_Wrap_Struct(cSennaRecords, 0, sen_records_close, _recs); } else { if (!rb_obj_is_kind_of(recs, cSennaRecords)) rb_raise(rb_eTypeError, "wrong argument type %s (expected Senna::Records)", rb_obj_classname(recs)); Data_Get_Struct(recs, sen_records, _recs); } _op = NIL_P(op) ? sen_sel_or : NUM2INT(op); if (NIL_P(optarg)) { _optarg_p = NULL; } else { VALUE mode, st, mi, wv, vs; sen_sel_mode _mode; int _st, _mi, *_wv, _vs; int i; Check_Type(optarg, T_HASH); mode = rb_hash_aref(optarg, ID2SYM(rb_intern("mode"))); _mode = NIL_P(mode) ? sen_sel_exact : NUM2INT(mode); st = rb_hash_aref(optarg, ID2SYM(rb_intern("similarity_threshold"))); _st = NIL_P(st) ? 0 : NUM2INT(st); mi = rb_hash_aref(optarg, ID2SYM(rb_intern("max_interval"))); _mi = NIL_P(mi) ? 0 : NUM2INT(mi); wv = rb_hash_aref(optarg, ID2SYM(rb_intern("weight_vector"))); if (!NIL_P(wv)) { Check_Type(wv, T_ARRAY); _wv = xmalloc(RARRAY_LEN(wv) * sizeof(int)); for (i = 0; i < RARRAY_LEN(wv); i += 1) { _wv[i] = NUM2INT(RARRAY_PTR(wv)[i]); } _vs = RARRAY_LEN(wv); } else { _wv = NULL; vs = rb_hash_aref(optarg, ID2SYM(rb_intern("vector_size"))); _vs = NIL_P(vs) ? 0 : NUM2INT(vs); } _optarg.mode = _mode; _optarg.similarity_threshold = _st; _optarg.max_interval = _mi; _optarg.weight_vector = _wv; _optarg.vector_size = _vs; _optarg.func = NULL; _optarg_p = &_optarg; } Data_Get_Struct(obj, struct index_data, data); if (data->closed) rb_raise(rb_eRuntimeError, "already closed"); rc = sen_index_select(data->indexp, RSTRING_PTR(string), RSTRING_LEN(string), _recs, _op, _optarg_p); if (rc != sen_success) senna_error(rc, "sen_index_select failed"); return recs; }