Class: Groonga::IndexColumn
- Defined in:
- ext/rb-grn-index-column.c,
ext/rb-grn-index-column.c
Overview
転置索引エントリを格納するカラム。このカラムを利用するこ とにより高速な全文検索を実現できる。
テーブルにGroonga::IndexColumnを定義する方法は Groonga::Table#define_index_columnを参照。
Instance Method Summary collapse
-
#[]= ⇒ Object
IDがidであるレコードを高速に全文検索するため転置索引を作 成する。多くの場合、Groonga::Table#define_index_columnで
:source
オプションを指定することにより、自動的に全文検索 用の索引は更新されるので、明示的にこのメソッドを使うこと は少ない。. -
#search ⇒ Object
call-seq: column.search(query, options={}) -> Groonga::Hash.
-
#source=(Groonga) ⇒ Object
インデックス対象となるカラムを設定する。.
-
#sources ⇒ Groonga::Columnの配列
インデックス対象となっているカラムの配列を返す。.
-
#sources=(Groonga) ⇒ Object
インデックス対象となる複数のカラムを配列で設定する。.
Methods inherited from Column
#clear_lock, #local_name, #lock, #locked?, #select, #table, #unlock
Instance Method Details
#[]=(id) ⇒ Object #[]=(id) ⇒ Object
IDがidであるレコードを高速に全文検索するため転置索引を作 成する。多くの場合、Groonga::Table#define_index_columnで :source
オプションを指定することにより、自動的に全文検索 用の索引は更新されるので、明示的にこのメソッドを使うこと は少ない。
valueには文字列を指定する。
optionsを指定することにより、より索引の作成を制御できる。 optionsに指定可能な値は以下の通り。
:section
-
段落番号を指定する。省略した場合は1を指定したとみなされ る。
Groonga::Table#define_index_columnで
{:with_section => true}
を指定していなければい けない。 :old_value
-
以前の値を指定する。省略した場合は現在の値が用いられる。 通常は指定する必要はない。
:value
-
新しい値を指定する。valueを指定した場合とoptionsで
{:value => value}
を指定した場合は同じ動作とな る。
記事の段落毎に索引を作成する。
articles = Groonga::Array.create(:name => "<articles>")
articles.define_column("title", "ShortText")
articles.define_column("content", "Text")
terms = Groonga::Hash.create(:name => "<terms>",
:default_tokenizer => "TokenBigram")
content_index = terms.define_index_column("content", articles,
:with_section => true)
content = <<-EOC
groonga は組み込み型の全文検索エンジンライブラリです。
DBMSやスクリプト言語処理系等に組み込むことによって、その
全文検索機能を強化することができます。また、リレーショナ
ルモデルに基づくデータストア機能を内包しており、groonga
単体でも高速なデータストアサーバとして使用することができ
ます。
■全文検索方式
転置索引型の全文検索エンジンです。転置索引は圧縮されてファ
イルに格納され、検索時のディスク読み出し量を小さく、かつ
局所的に抑えるように設計されています。用途に応じて以下の
索引タイプを選択できます。
EOC
groonga = articles.add(:title => "groonga", :content => content)
content.split(/\n{2,}/).each_with_index do |sentence, i|
content_index[groonga] = {:value => sentence, :section => i + 1}
end
content_index.search("エンジン").collect do |record|
p record.key["title"] # -> "groonga"
end
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'ext/rb-grn-index-column.c', line 166
static VALUE
rb_grn_index_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
{
grn_ctx *context = NULL;
grn_obj *column, *range;
grn_rc rc;
grn_id id;
unsigned int section;
grn_obj *old_value, *new_value;
VALUE original_rb_value, rb_section, rb_old_value, rb_new_value;
original_rb_value = rb_value;
rb_grn_index_column_deconstruct(SELF(self), &column, &context,
NULL, NULL,
&new_value, &old_value,
NULL, &range,
NULL, NULL);
id = RVAL2GRNID(rb_id, context, range, self);
if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) {
VALUE hash_value;
hash_value = rb_hash_new();
rb_hash_aset(hash_value, RB_GRN_INTERN("value"), rb_value);
rb_value = hash_value;
}
rb_grn_scan_options(rb_value,
"section", &rb_section,
"old_value", &rb_old_value,
"value", &rb_new_value,
NULL);
if (NIL_P(rb_section))
section = 1;
else
section = NUM2UINT(rb_section);
if (NIL_P(rb_old_value)) {
old_value = NULL;
} else {
GRN_BULK_REWIND(old_value);
RVAL2GRNBULK(rb_old_value, context, old_value);
}
if (NIL_P(rb_new_value)) {
new_value = NULL;
} else {
GRN_BULK_REWIND(new_value);
RVAL2GRNBULK(rb_new_value, context, new_value);
}
rc = grn_column_index_update(context, column,
id, section, old_value, new_value);
rb_grn_context_check(context, self);
rb_grn_rc_check(rc, self);
return original_rb_value;
}
|
#search ⇒ Object
call-seq:
column.search(query, options={}) -> Groonga::Hash
objectからqueryに対応するオブジェクトを検索し、見つかっ たオブジェクトのIDがキーになっているGroonga::Hashを返す。
利用可能なオプションは以下の通り。
- :result
-
結果を格納するGroonga::Hash。指定しない場合は新しく Groonga::Hashを生成し、それに結果を格納して返す。
- :operator
-
以下のどれかの値を指定する。
nil
,"or"
,"||"
,"and"
,"+"
,"&&"
,"but"
,"not"
,"-"
,"adjust"
,">"
。 それぞれ以下のようになる。(FIXME: 「以下」) - :exact
-
true
を指定すると完全一致で検索する - :longest_common_prefix
-
true
を指定するとqueryと同じ接頭辞をもつエントリのう ち、もっとも長いエントリを検索する - :suffix
-
true
を指定するとqueryが後方一致するエントリを検索す る - :prefix
-
true
を指定するとqueryが前方一致するレコードを検索す る - :near
-
true
を指定するとqueryに指定した複数の語が近傍に含ま れるレコードを検索する - …
-
…
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'ext/rb-grn-index-column.c', line 412
static VALUE
rb_grn_index_column_search (int argc, VALUE *argv, VALUE self)
{
grn_ctx *context;
grn_obj *column;
grn_obj *range;
grn_obj *query = NULL, *id_query = NULL, *string_query = NULL;
grn_obj *result;
grn_operator operator;
grn_rc rc;
VALUE rb_query, options, rb_result, rb_operator;
rb_grn_index_column_deconstruct(SELF(self), &column, &context,
NULL, NULL,
NULL, NULL, NULL, &range,
&id_query, &string_query);
rb_scan_args(argc, argv, "11", &rb_query, &options);
if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cGrnQuery))) {
grn_query *_query;
_query = RVAL2GRNQUERY(rb_query);
query = (grn_obj *)_query;
} else if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cInteger))) {
grn_id id;
id = NUM2UINT(rb_query);
GRN_TEXT_SET(context, id_query, &id, sizeof(grn_id));
query = id_query;
} else {
const char *_query;
_query = StringValuePtr(rb_query);
GRN_TEXT_SET(context, string_query, _query, RSTRING_LEN(rb_query));
query = string_query;
}
rb_grn_scan_options(options,
"result", &rb_result,
"operator", &rb_operator,
NULL);
if (NIL_P(rb_result)) {
result = grn_table_create(context, NULL, 0, NULL,
GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
range, 0);
rb_grn_context_check(context, self);
rb_result = GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
} else {
result = RVAL2GRNOBJECT(rb_result, &context);
}
operator = RVAL2GRNOPERATOR(rb_operator);
rc = grn_obj_search(context, column, query, result, operator, NULL);
rb_grn_rc_check(rc, self);
return rb_result;
}
|
#source=(Groonga) ⇒ Object
インデックス対象となるカラムを設定する。
367 368 369 370 371 372 373 374 |
# File 'ext/rb-grn-index-column.c', line 367
static VALUE
rb_grn_index_column_set_source (VALUE self, VALUE rb_source)
{
if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_source, rb_cArray)))
rb_source = rb_ary_new3(1, rb_source);
return rb_grn_index_column_set_sources(self, rb_source);
}
|
#sources ⇒ Groonga::Columnの配列
インデックス対象となっているカラムの配列を返す。
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'ext/rb-grn-index-column.c', line 233
static VALUE
rb_grn_index_column_get_sources (VALUE self)
{
grn_ctx *context = NULL;
grn_obj *column;
grn_obj sources;
grn_id *source_ids;
VALUE rb_sources;
int i, n;
rb_grn_index_column_deconstruct(SELF(self), &column, &context,
NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
GRN_OBJ_INIT(&sources, GRN_BULK, 0, GRN_ID_NIL);
grn_obj_get_info(context, column, GRN_INFO_SOURCE, &sources);
rb_grn_context_check(context, self);
n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
rb_sources = rb_ary_new2(n);
for (i = 0; i < n; i++) {
grn_obj *source;
VALUE rb_source;
source = grn_ctx_at(context, *source_ids);
rb_source = GRNOBJECT2RVAL(Qnil, context, source, RB_GRN_FALSE);
rb_ary_push(rb_sources, rb_source);
source_ids++;
}
grn_obj_close(context, &sources);
return rb_sources;
}
|
#sources=(Groonga) ⇒ Object
インデックス対象となる複数のカラムを配列で設定する。
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'ext/rb-grn-index-column.c', line 322
static VALUE
rb_grn_index_column_set_sources (VALUE self, VALUE rb_sources)
{
VALUE exception;
grn_ctx *context = NULL;
grn_obj *column;
int i, n;
VALUE *rb_source_values;
grn_id *sources;
grn_rc rc;
rb_grn_index_column_deconstruct(SELF(self), &column, &context,
NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
n = RARRAY_LEN(rb_sources);
rb_source_values = RARRAY_PTR(rb_sources);
sources = ALLOCA_N(grn_id, n);
for (i = 0; i < n; i++) {
sources[i] = resolve_source_id(context, column, rb_source_values[i]);
}
{
grn_obj bulk_sources;
GRN_OBJ_INIT(&bulk_sources, GRN_BULK, 0, GRN_ID_NIL);
GRN_TEXT_SET(context, &bulk_sources, sources, n * sizeof(grn_id));
rc = grn_obj_set_info(context, column, GRN_INFO_SOURCE, &bulk_sources);
exception = rb_grn_context_to_exception(context, self);
grn_obj_close(context, &bulk_sources);
}
if (!NIL_P(exception))
rb_exc_raise(exception);
rb_grn_rc_check(rc, self);
return Qnil;
}
|