/* * Document-method: unlock * * call-seq: * database.unlock * * _database_ のロックを解除する。 */ static VALUE rb_grn_database_unlock (VALUE self) { grn_ctx *context; grn_obj *database; grn_rc rc; rb_grn_database_deconstruct(SELF(self), &database, &context, NULL, NULL, NULL, NULL); rc = grn_obj_unlock(context, database, GRN_ID_NIL); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * _key_ にマッチするレコードのIDがキーに入っている * {Groonga::Hash} を返す。マッチするレコードがない場合は空の * {fGroonga::Hash} が返る。 * _options_ で +:result+ を指定することにより、そのテーブルにマッ * チしたレコードIDがキーのレコードを追加することができる。 * +:result+ にテーブルを指定した場合は、そのテーブルが返る。 * * @example 複数のキーで検索し、結果を1つのテーブルに集める。 * result = nil * keys = ["morita", "gunyara-kun", "yu"] * keys.each do |key| * result = users.search(key, :result => result) * end * result.each do |record| * user = record.key * p user.key # -> "morita"または"gunyara-kun"または"yu" * end * * @overload search(key, options=nil) * @return [Groonga::Hash] * @param key [String] レコードにマッチさせる値 * @param options [::Hash] The name and value * pairs. Omitted names are initialized as the default value. * @option options :result The result * 結果を格納するテーブル。 * @option options :operator (Groonga::Operator::OR) * マッチしたレコードをどのように扱うか。指定可能な値は以 * 下の通り。 * * - Groonga::Operator::OR := * マッチしたレコードを追加。すでにレコードが追加され * ている場合は何もしない。 =: * - Groonga::Operator::AND := * マッチしたレコードのスコアを増加。マッチしなかった * レコードを削除。 =: * - Groonga::Operator::AND_NOT := * マッチしたレコードを削除。 =: * - Groonga::Operator::ADJUST := * マッチしたレコードのスコアを増加。 =: * - +:type+ := * ????? =: * */ static VALUE rb_grn_double_array_trie_search (int argc, VALUE *argv, VALUE self) { grn_rc rc; grn_ctx *context; grn_obj *table; grn_id domain_id; grn_obj *key, *domain, *result; grn_operator operator; grn_search_optarg search_options; grn_bool search_options_is_set = GRN_FALSE; VALUE rb_key, options, rb_result, rb_operator, rb_type; rb_grn_double_array_trie_deconstruct(SELF(self), &table, &context, &key, NULL, &domain_id, &domain, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_key, &options); RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self); rb_grn_scan_options(options, "result", &rb_result, "operator", &rb_operator, "type", &rb_type, NULL); if (NIL_P(rb_result)) { result = grn_table_create(context, NULL, 0, NULL, GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, table, 0); rb_grn_context_check(context, self); rb_result = GRNOBJECT2RVAL(Qnil, context, result, GRN_TRUE); } else { result = RVAL2GRNOBJECT(rb_result, &context); } operator = RVAL2GRNOPERATOR(rb_operator); rc = grn_obj_search(context, table, key, result, operator, search_options_is_set ? &search_options : NULL); rb_grn_rc_check(rc, self); return rb_result; }
/* * _expression_ をコンパイルする。 * * @overload compile */ static VALUE rb_grn_expression_compile (VALUE self) { grn_ctx *context = NULL; grn_obj *expression; grn_rc rc; rb_grn_expression_deconstruct(SELF(self), &expression, &context, NULL, NULL, NULL, NULL, NULL); rc = grn_expr_compile(context, expression); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * call-seq: * table_cursor.delete * * カレントレコードを削除する。 */ static VALUE rb_grn_table_cursor_delete (VALUE self) { grn_ctx *context; grn_table_cursor *cursor; rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context, NULL, NULL, NULL, NULL); if (context && cursor) { grn_rc rc; rc = grn_table_cursor_delete(context, cursor); rb_grn_rc_check(rc, self); } return Qnil; }
/* * Recreates all index columns for the column. * * This method is useful when you have any broken index columns for * the column. You don't need to specify each index column. But this * method spends more time rather than you specify only reindex * needed index columns. * * You can use {Groonga::Database#reindex} to recreate all index * columns in a database. * * You can use {Groonga::TableKeySupport#reindex} to recreate all * index columns in a table. * * You can use {Groonga::IndexColumn#reindex} to specify the reindex * target index column. * * @example How to recreate all index columns for the column * Groonga::Schema.define do |schema| * schema.create_table("Memos") do |table| * table.short_text("title") * table.text("content") * end * * schema.create_table("BigramTerms", * :type => :patricia_trie, * :key_type => :short_text, * :normalizer => "NormalizerAuto", * :default_tokenizer => "TokenBigram") do |table| * table.index("Memos.title") * table.index("Memos.content") * end * * schema.create_table("MeCabTerms", * :type => :patricia_trie, * :key_type => :short_text, * :normalizer => "NormalizerAuto", * :default_tokenizer => "TokenMecab") do |table| * table.index("Memos.title") * table.index("Memos.content") * end * end * * Groonga["Memos.content"].reindex * # They are called: * # Groonga["BigramTerms.Memos_content"].reindex * # Groonga["MeCabTerms.Memos_content"].reindex * # * # They aren't called: * # Groonga["BigramTerms.Memos_title"].reindex * # Groonga["MeCabTerms.Memos_title"].reindex * * @overload reindex * @return [void] * * @see Groonga::Database#reindex * @see Groonga::TableKeySupport#reindex * @see Groonga::FixSizeColumn#reindex * @see Groonga::IndexColumn#reindex * * @since 5.1.1 */ static VALUE rb_grn_variable_size_column_reindex (VALUE self) { grn_rc rc; grn_ctx *context; grn_obj *column; rb_grn_variable_size_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL, NULL); rc = grn_obj_reindex(context, column); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
void Init_groonga (void) { VALUE mGrn; mGrn = rb_define_module("Groonga"); rb_grn_init_exception(mGrn); rb_grn_rc_check(grn_init(), Qnil); rb_set_end_proc(finish_groonga, Qnil); rb_grn_init_version(mGrn); rb_grn_init_lock_timeout(mGrn); rb_grn_init_utils(mGrn); rb_grn_init_encoding(mGrn); rb_grn_init_encoding_support(mGrn); rb_grn_init_context(mGrn); rb_grn_init_object(mGrn); rb_grn_init_database(mGrn); rb_grn_init_table(mGrn); rb_grn_init_table_cursor(mGrn); rb_grn_init_index_cursor(mGrn); rb_grn_init_posting(mGrn); rb_grn_init_type(mGrn); rb_grn_init_procedure(mGrn); rb_grn_init_procedure_type(mGrn); rb_grn_init_column(mGrn); rb_grn_init_accessor(mGrn); rb_grn_init_geo_point(mGrn); rb_grn_init_record(mGrn); rb_grn_init_variable(mGrn); rb_grn_init_operator(mGrn); rb_grn_init_expression(mGrn); rb_grn_init_expression_builder(mGrn); rb_grn_init_logger(mGrn); rb_grn_init_query_logger(mGrn); rb_grn_init_snippet(mGrn); rb_grn_init_plugin(mGrn); rb_grn_init_normalizer(mGrn); }
/* * Removes an object forcibly. * * Normally, you should use {Groonga::Object#remove}. * * @overload remove_force(name) * * @param [String] name The target object name. * * @since 6.0.9 */ static VALUE rb_grn_database_remove_force (VALUE self, VALUE rb_name) { grn_rc rc; grn_ctx *context; char *name; int name_size; rb_grn_database_deconstruct(SELF(self), NULL, &context, NULL, NULL, NULL, NULL); name = StringValueCStr(rb_name); name_size = RSTRING_LEN(rb_name); rc = grn_obj_remove_force(context, name, name_size); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * call-seq: * cursor.value = 値 * * カレントレコードの値を設定する。既存の値は上書きされる。 */ static VALUE rb_grn_table_cursor_set_value (VALUE self, VALUE value) { grn_ctx *context; grn_table_cursor *cursor; rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context, NULL, NULL, NULL, NULL); if (context && cursor) { grn_rc rc; rc = grn_table_cursor_set_value(context, cursor, StringValuePtr(value), GRN_OBJ_SET); rb_grn_rc_check(rc, self); } return Qnil; }
/* * Specifies the normalizer used by {Groonga::IndexColumn}. * * @example * # Uses NFKC normalizer. * table.normalizer = "NormalizerNFKC51" * # Specifies normalizer object. * table.normalizer = Groonga::Context["NormalizerNFKC51"] * # Uses auto normalizer that is a normalizer for backward compatibility. * table.normalizer = "TNormalizerAuto" * * @overload normalizer=(name) * @param [String] name Set a nomalizer named @name@. * * @overload normalizer=(normalizer) * @param [Groonga::Procedure] normalizer Set the normalizer object. * * @overload normalizer=(normalizer) * @param [nil] normalizer Unset normalizer. */ static VALUE rb_grn_table_key_support_set_normalizer (VALUE self, VALUE rb_normalizer) { grn_ctx *context; grn_obj *table; grn_obj *normalizer; grn_rc rc; rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, NULL, NULL, NULL, NULL, NULL, NULL, NULL); normalizer = RVAL2GRNOBJECT(rb_normalizer, &context); rc = grn_obj_set_info(context, table, GRN_INFO_NORMALIZER, normalizer); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * インデックス対象となる複数のカラムを配列で設定する。 * * @overload sources=(columns) * @param [::Array<Groonga::Column>] columns インデックス対象となるカラムの配列 */ 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 range_id; grn_id *sources; grn_rc rc; rb_grn_index_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, &range_id, 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, range_id, 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_unlink(context, &bulk_sources); } if (!NIL_P(exception)) rb_exc_raise(exception); rb_grn_rc_check(rc, self); return Qnil; }
/* * call-seq: * snippet.add_keyword(keyword, options={}) * * _keyword_を追加する。_options_に指定可能な値は以下の通 * り。 * * [+:open_tag+] * 開始タグ。省略した場合はGroonga::Snippet.newで指定し * た+:default_open_tag+。 * * [+:close_tag+] * 終了タグ。省略した場合はGroonga::Snippet.newで指定し * た+:default_close_tag+。 */ static VALUE rb_grn_snippet_add_keyword (int argc, VALUE *argv, VALUE self) { RbGrnSnippet *rb_grn_snippet; grn_rc rc; VALUE rb_keyword, options; VALUE rb_open_tag, rb_close_tag; char *keyword, *open_tag = NULL, *close_tag = NULL; unsigned int keyword_length, open_tag_length = 0, close_tag_length = 0; rb_scan_args(argc, argv, "11", &rb_keyword, &options); rb_grn_snippet = SELF(self); keyword = StringValuePtr(rb_keyword); keyword_length = RSTRING_LEN(rb_keyword); rb_grn_scan_options(options, "open_tag", &rb_open_tag, "close_tag", &rb_close_tag, NULL); if (!NIL_P(rb_open_tag)) { open_tag = StringValuePtr(rb_open_tag); open_tag_length = RSTRING_LEN(rb_open_tag); } if (!NIL_P(rb_close_tag)) { close_tag = StringValuePtr(rb_close_tag); close_tag_length = RSTRING_LEN(rb_close_tag); } rc = grn_snip_add_cond(rb_grn_snippet->context, rb_grn_snippet->snippet, keyword, keyword_length, open_tag, open_tag_length, close_tag, close_tag_length); rb_grn_rc_check(rc, self); return Qnil; }
/* * {Groonga::IndexColumn} で使用するトークナイザを設定する。 * * @example * # 2-gramを使用。 * table.default_tokenizer = "TokenBigram" * # オブジェクトで指定 * table.default_tokenizer = Groonga::Context.default["TokenBigram"] * # オブジェクトIDで指定 * table.default_tokenizer = Groonga::Type::BIGRAM * # N-gram用のトークナイザを使うときはGroonga::IndexColumn * # には自動的に:with_section => trueが指定される。 * index = table.define_index_column("blog_content", "Blogs", * :source => "content") * p index # -> #<Groonga::IndexColumn ... flags: <WITH_POSITION|...>> * * # MeCabを使用 * table.default_tokenizer = "TokenMecab" * * @overload default_tokenizer=(tokenizer) */ static VALUE rb_grn_table_key_support_set_default_tokenizer (VALUE self, VALUE rb_tokenizer) { grn_ctx *context; grn_obj *table; grn_obj *tokenizer; grn_rc rc; rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, NULL, NULL, NULL, NULL, NULL, NULL, NULL); tokenizer = RVAL2GRNOBJECT(rb_tokenizer, &context); rc = grn_obj_set_info(context, table, GRN_INFO_DEFAULT_TOKENIZER, tokenizer); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * Deletes a record that has @value@ content from inverted * index. Normally, this method is not used explicitly. Inverted index * for fulltext search is updated automatically by using @:source@ * option of {Groonga::Table#define_index_column}. * * @example Deletes sentences of an article to index * articles = Groonga::Array.create(:name => "Articles") * articles.define_column("title", "ShortText") * articles.define_column("content", "Text") * * terms = Groonga::Hash.create(:name => "Terms", * :key_type => "ShortText", * :default_tokenizer => "TokenBigram") * content_index = terms.define_index_column("content", articles, * :with_position => true, * :with_section => true) * * content = <<-CONTENT * Groonga is a fast and accurate full text search engine based on * inverted index. One of the characteristics of groonga is that a * newly registered document instantly appears in search * results. Also, groonga allows updates without read locks. These * characteristics result in superior performance on real-time * applications. * * Groonga is also a column-oriented database management system * (DBMS). Compared with well-known row-oriented systems, such as * MySQL and PostgreSQL, column-oriented systems are more suited for * aggregate queries. Due to this advantage, groonga can cover * weakness of row-oriented systems. * * The basic functions of groonga are provided in a C library. Also, * libraries for using groonga in other languages, such as Ruby, are * provided by related projects. In addition, groonga-based storage * engines are provided for MySQL and PostgreSQL. These libraries * and storage engines allow any application to use groonga. See * usage examples. * CONTENT * * groonga = articles.add(:title => "groonga", :content => content) * * content.split(/\n{2,}/).each_with_index do |sentence, i| * content_index.add(groonga, sentence, :section => i + 1) * end * * content_index.search("engine").each do |record| * p record.key["title"] # -> "groonga" * end * * content.split(/\n{2,}/).each_with_index do |sentence, i| * content_index.delete(groonga, sentence, :section => i + 1) * end * * p content_index.search("engine").size # -> 0 * * @overload delete(record, value, options={}) * @param [Groonga::Record, Integer] record * The record that has a @value@ as its value. It can be Integer as * record id. * @param [String] value * The value of the @record@. * @param [::Hash] options * The options. * @option options [Integer] :section (1) * The section number. It is one-origin. * * You must specify @{:with_section => true}@ in * {Groonga::Table#define_index_column} to use this option. * @return [void] * * @since 3.0.2 */ static VALUE rb_grn_index_column_delete (int argc, VALUE *argv, VALUE self) { grn_ctx *context = NULL; grn_obj *column, *range; grn_rc rc; grn_id id; unsigned int section; grn_obj *old_value; VALUE rb_record, rb_value, rb_options, rb_section; rb_scan_args(argc, argv, "21", &rb_record, &rb_value, &rb_options); rb_grn_index_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, &old_value, NULL, &range, NULL, NULL); id = RVAL2GRNID(rb_record, context, range, self); GRN_BULK_REWIND(old_value); RVAL2GRNBULK(rb_value, context, old_value); rb_grn_scan_options(rb_options, "section", &rb_section, NULL); if (NIL_P(rb_section)) { section = 1; } else { section = NUM2UINT(rb_section); } rc = grn_column_index_update(context, column, id, section, old_value, NULL); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return self; }
static VALUE rb_grn_double_array_trie_update_by_id (VALUE self, VALUE rb_id, VALUE rb_new_key) { grn_ctx *context; grn_obj *table; grn_id id, domain_id; grn_obj *new_key, *domain; grn_rc rc; rb_grn_double_array_trie_deconstruct(SELF(self), &table, &context, NULL, &new_key, &domain_id, &domain, NULL, NULL, NULL, NULL); id = NUM2UINT(rb_id); RVAL2GRNKEY(rb_new_key, context, new_key, domain_id, domain, self); rc = grn_table_update_by_id(context, table, id, GRN_BULK_HEAD(new_key), GRN_BULK_VSIZE(new_key)); rb_grn_rc_check(rc, self); return Qnil; }
/* * Document-method: rename * * call-seq: * table.rename(name) * * Renames the table to name. * * @param name [String] the new name * @since 1.3.0 */ static VALUE rb_grn_column_rename (VALUE self, VALUE rb_name) { int rc; grn_ctx *context; grn_obj *column; char *name; int name_size; rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); name = StringValueCStr(rb_name); name_size = RSTRING_LEN(rb_name); rc = grn_column_rename(context, column, name, name_size); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return self; }
/* * _key_ にマッチするレコードのIDがキーに入っている * {Groonga::Hash} を返す。マッチするレコードがない場合は空の * {Groonga::Hash} が返る。 * * _options_ で +:result+ を指定することにより、そのテーブルにマッ * チしたレコードIDがキーのレコードを追加することができる。 * +:result+ にテーブルを指定した場合は、そのテーブルが返る。 * * @example 複数のキーで検索し、結果を1つのテーブルに集める。 * result = nil * keys = ["morita", "gunyara-kun", "yu"] * keys.each do |key| * result = users.search(key, :result => result) * end * result.each do |record| * user = record.key * p user.key # -> "morita"または"gunyara-kun"または"yu" * end * * @overload search(key, options=nil) * @param [::Hash] options The name and value * pairs. Omitted names are initialized as the default value * @option options :result * 結果を格納するテーブル。 * @return [Groonga::Hash] */ static VALUE rb_grn_hash_search (int argc, VALUE *argv, VALUE self) { grn_rc rc; grn_ctx *context; grn_obj *table; grn_id domain_id; grn_obj *key, *domain, *result; VALUE rb_key, options, rb_result; rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, &key, &domain_id, &domain, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_key, &options); RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self); rb_grn_scan_options(options, "result", &rb_result, NULL); if (NIL_P(rb_result)) { result = grn_table_create(context, NULL, 0, NULL, GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, table, 0); rb_grn_context_check(context, self); rb_result = GRNOBJECT2RVAL(Qnil, context, result, GRN_TRUE); } else { result = RVAL2GRNOBJECT(rb_result, &context); } rc = grn_obj_search(context, table, key, result, GRN_OP_OR, NULL); rb_grn_rc_check(rc, self); return rb_result; }
static VALUE rb_grn_table_key_support_delete_by_key (VALUE self, VALUE rb_key) { grn_ctx *context; grn_obj *table; grn_id domain_id; grn_obj *key, *domain; grn_rc rc; rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, &key, &domain_id, &domain, NULL, NULL, NULL, NULL); GRN_BULK_REWIND(key); RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self); rc = grn_table_delete(context, table, GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key)); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * Document-method: lock * * call-seq: * column.lock(options={}) * column.lock(options={}) {...} * * _column_をロックする。ロックに失敗した場合は * Groonga::ResourceDeadlockAvoided例外が発生する。 * * ブロックを指定した場合はブロックを抜けたときにunlockする。 * * 利用可能なオプションは以下の通り。 * * [_:timeout_] * ロックを獲得できなかった場合は_:timeout_秒間ロックの獲 * 得を試みる。_:timeout_秒以内にロックを獲得できなかった * 場合は例外が発生する。 * [_:id_] * _:id_で指定したレコードをロックする。(注: groonga側が * 未実装のため、現在は無視される) */ static VALUE rb_grn_column_lock (int argc, VALUE *argv, VALUE self) { grn_id id = GRN_ID_NIL; grn_ctx *context; grn_obj *column; int timeout = 0; grn_rc rc; VALUE options, rb_timeout, rb_id; rb_scan_args(argc, argv, "01", &options); rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); rb_grn_scan_options(options, "timeout", &rb_timeout, "id", &rb_id, NULL); if (!NIL_P(rb_timeout)) timeout = NUM2UINT(rb_timeout); if (!NIL_P(rb_id)) id = NUM2UINT(rb_id); rc = grn_obj_lock(context, column, id, timeout); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); if (rb_block_given_p()) { return rb_ensure(rb_yield, Qnil, rb_grn_column_unlock_ensure, self); } else { return Qnil; } }
static VALUE rb_grn_table_key_support_set_value_by_key (VALUE self, VALUE rb_key, VALUE rb_value) { grn_ctx *context; grn_obj *table; grn_id id; grn_obj *value; grn_rc rc; if (NIL_P(rb_key)) { rb_raise(rb_eArgError, "key should not be nil: <%s>", rb_grn_inspect(self)); } rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, NULL, NULL, NULL, &value, NULL, NULL, NULL); id = rb_grn_table_key_support_add_raw(self, rb_key, NULL); if (GRN_ID_NIL == id) { rb_raise(rb_eGrnError, "failed to add new record with key: <%s>: <%s>", rb_grn_inspect(rb_key), rb_grn_inspect(self)); } GRN_BULK_REWIND(value); RVAL2GRNBULK(rb_value, context, value); rc = grn_obj_set_value(context, table, id, value, GRN_OBJ_SET); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return rb_value; }
/* * Sets token filters that used in {Groonga::IndexColumn}. * * @example * # Use "TokenFilterStem" and "TokenfilterStopWord" * table.token_filters = ["TokenFilterStem", "TokenFilterStopWord"] * * @overload token_filters=(token_filters) * @param token_filters [::Array<String>] Token filter names. */ static VALUE rb_grn_table_key_support_set_token_filters (VALUE self, VALUE rb_token_filters) { grn_ctx *context; grn_obj *table; grn_obj token_filters; grn_rc rc; rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, NULL, NULL, NULL, NULL, NULL, NULL, NULL); GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL); RVAL2GRNPVECTOR(rb_token_filters, context, &token_filters); rc = grn_obj_set_info(context, table, GRN_INFO_TOKEN_FILTERS, &token_filters); grn_obj_unlink(context, &token_filters); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * call-seq: * context.connect(options=nil) * * groongaサーバに接続する。_options_に指定可能な値は以下の通 * り。 * * [+:host+] * groongaサーバのホスト名。またはIPアドレス。省略すると * "localhost"に接続する。 * * [+:port+] * groongaサーバのポート番号。省略すると10041番ポートに接 * 続する。 */ static VALUE rb_grn_context_connect (int argc, VALUE *argv, VALUE self) { grn_ctx *context; const char *host; int port; int flags = 0; grn_rc rc; VALUE options, rb_host, rb_port; rb_scan_args(argc, argv, "01", &options); rb_grn_scan_options(options, "host", &rb_host, "port", &rb_port, NULL); context = SELF(self); if (NIL_P(rb_host)) { host = "localhost"; } else { host = StringValueCStr(rb_host); } if (NIL_P(rb_port)) { port = 10041; } else { port = NUM2INT(rb_port); } rc = grn_ctx_connect(context, host, port, flags); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return Qnil; }
/* * It updates a value of variable size column value for the record * that ID is _id_. * * Weight vector column is a special variable size column. This * description describes only weight vector column. Other variable * size column works what you think. * * @example Use weight vector as matrix search result weight * Groonga::Schema.define do |schema| * schema.create_table("Products", * :type => :patricia_trie, * :key_type => "ShortText") do |table| * # This is weight vector. * # ":with_weight => true" is important for matrix search result weight. * table.short_text("tags", * :type => :vector, * :with_weight => true) * end * * schema.create_table("Tags", * :type => :hash, * :key_type => "ShortText") do |table| * # This is inverted index. It also needs ":with_weight => true". * table.index("Products.tags", :with_weight => true) * end * end * * products = Groonga["Products"] * groonga = products.add("Groonga") * groonga.tags = [ * { * :value => "groonga", * :weight => 100, * }, * ] * rroonga = products.add("Rroonga") * rroonga.tags = [ * { * :value => "ruby", * :weight => 100, * }, * { * :value => "groonga", * :weight => 10, * }, * ] * * result = products.select do |record| * # Search by "groonga" * record.match("groonga") do |match_target| * match_target.tags * end * end * * result.each do |record| * p [record.key.key, record.score] * end * # Matches all records with weight. * # => ["Groonga", 101] * # ["Rroonga", 11] * * # Increases score for "ruby" 10 times * products.select(# The previous search result. Required. * :result => result, * # It just adds score to existing records in the result. Required. * :operator => Groonga::Operator::ADJUST) do |record| * record.match("ruby") do |target| * target.tags * 10 # 10 times * end * end * * result.each do |record| * p [record.key.key, record.score] * end * # Weight is used for increasing score. * # => ["Groonga", 101] <- Not changed. * # ["Rroonga", 1021] <- 1021 (= 101 * 10 + 1) increased. * * @overload []=(id, elements) * This description is for weight vector column. * * @param [Integer, Record] id The record ID. * @param [Array<Hash<Symbol, String>>] elements An array of values * for weight vector. * Each value is a Hash like the following form: * * <pre> * { * :value => [KEY], * :weight => [WEIGHT], * } * </pre> * * @[KEY]@ must be the same type of the key of the table that is * specified as range on creating the weight vector. * * @[WEIGHT]@ must be an positive integer. Note that search * becomes @weight + 1@. It means that You want to get 10 as * score, you should set 9 as weight. * * @overload []=(id, value) * This description is for variable size columns except weight * vector column. * * @param [Integer, Record] id The record ID. * @param [::Object] value A new value. * @see Groonga::Object#[]= * * @since 4.0.1 */ static VALUE rb_grn_variable_size_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; grn_obj *value, *element_value; int flags = GRN_OBJ_SET; rb_grn_variable_size_column_deconstruct(SELF(self), &column, &context, NULL, NULL, &value, &element_value, NULL, &range); if (!(column->header.flags & GRN_OBJ_WITH_WEIGHT)) { VALUE args[2]; args[0] = rb_id; args[1] = rb_value; return rb_call_super(2, args); } id = RVAL2GRNID(rb_id, context, range, self); grn_obj_reinit(context, value, value->header.domain, value->header.flags | GRN_OBJ_VECTOR); value->header.flags |= GRN_OBJ_WITH_WEIGHT; if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cArray))) { int i, n; n = RARRAY_LEN(rb_value); for (i = 0; i < n; i++) { unsigned int weight = 0; VALUE rb_element_value, rb_weight; rb_grn_scan_options(RARRAY_PTR(rb_value)[i], "value", &rb_element_value, "weight", &rb_weight, NULL); if (!NIL_P(rb_weight)) { weight = NUM2UINT(rb_weight); } if (value->header.type == GRN_UVECTOR) { grn_id id = RVAL2GRNID(rb_element_value, context, range, self); grn_uvector_add_element(context, value, id, weight); } else { GRN_BULK_REWIND(element_value); if (!NIL_P(rb_element_value)) { RVAL2GRNBULK(rb_element_value, context, element_value); } grn_vector_add_element(context, value, GRN_BULK_HEAD(element_value), GRN_BULK_VSIZE(element_value), weight, element_value->header.domain); } } } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) { HashElementToVectorElementData data; data.self = self; data.context = context; data.vector = value; data.element_value = element_value; data.range = range; rb_hash_foreach(rb_value, hash_element_to_vector_element, (VALUE)&data); } else { rb_raise(rb_eArgError, "<%s>: " "weight vector value must be an array of index value or " "a hash that key is vector value and value is vector weight: " "<%s>", rb_grn_inspect(self), rb_grn_inspect(rb_value)); } rc = grn_obj_set_value(context, column, id, value, flags); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); return rb_value; }