Ruby - Rroonga で全文検索!

Updated:


Ruby でカラムストア機能付き全文検索エンジン Groonga の機能を容易に使用できる Rroonga を使用してみました。

0. 前提条件

  • Linux Mint 17.2(64bit) での作業を想定。
  • Ruby 2.2.2-p95 での作業を想定。
  • カラムストア機能付き全文検索エンジン Groonga がインストール済みであること。

1. Rroonga のインストール

以下のようにしてインストールする。
(ちなみ、 Groonga 未インストールなら、ここでインストールされるはず。(当方 Groonga インストール済みなので、未確認))

$ sudo gem install rroonga

2. データベースの作成

簡単な都道府県名データベースを作成してみる。

取り急ぎ対話形式で作業を行いたいので、 pry(or irb) に入る。(プロンプトを簡易表示。 groongarequire して)

$ pry --simple-prompt -r groonga

まず、エンコーディングの設定を行う。(今回は Linux なので UTF-8 に設定)

>> Groonga::Context.default_options = {:encoding => :utf8}
=> {:encoding=>:utf8}

そして、データベースを作成する。(データベースファイル名を指定)

>> Groonga::Database.create(:path => "/path/to/prefs.db")
=> #<Groonga::Database id: <nil>, name: (anonymous), path: </path/to/prefs.db>, domain: (nil), range: (nil), flags: <>>

3. テーブルの作成

都道府県名テーブルを作成してみる。(テーブル名、テーブルタイプを指定)
(テーブルタイプには hash, patricia_trie, double_array_trie, array が指定可能)

>> Groonga::Schema.create_table("Prefs", :type => :hash) do |tbl|
 |   tbl.text("pref_name")
 | end
=> [#<Groonga::Schema::TableDefinition:0x007f9fe62cef60
  @definitions=
   [#<Groonga::Schema::ColumnDefinition:0x007f9fe62ce1f0
     @name="pref_name",
     @options={:persistent=>true, :named_path=>nil},
     @type="Text">],
  @name="Prefs",
  @options=
   {:context=>
     #<Groonga::Context encoding: <:utf8>, database: <#<Groonga::Database id: <nil>, name: (anonymous), path: </path/to/prefs.db>, domain: (nil), range: (nil), flags: <>>>>,
    :type=>:hash},
  @table_type=Groonga::Hash>]

テーブルが作成されたか確認してみる。

>> prefs = Groonga["Prefs"]
=> #<Groonga::Hash id: <256>, name: <Prefs>, path: </path/to/prefs.db.0000100>, domain: <ShortText>, range: (nil), flags: <>, size: <0>, encoding: <:utf8>, default_tokenizer: (nil), token_filters: [], normalizer: (nil)>
>> prefs.size
=> 0

4. レコードの追加

以下のようにして、テーブルにレコードを追加していく。(47都道府県分。別途作成しておいた配列をループさせて登録するのがよいだろう)

>> prefs.add("Hokkaido", :pref_name => "北海道")
=> #<Groonga::Record:0x007f9fe69e4480 ..., attributes: {"_id"=>1, "_key"=>"Hokkaido", "pref_name"=>"北海道"}>

以下のような方法で追加することも可能。

>> prefs.add("Aomoriken")
=> #<Groonga::Record:0x007f9fe6755020 ..., attributes: {"_id"=>3, "_key"=>"Aomoriken", "pref_name"=>nil}>
>> prefs["Aomoriken"].pref_name = "青森県"
=> "青森県"

ちなみに、削除するには以下のようにする。

>> prefs.delete("Aomoriken")
=> nil

5. レコードの参照

登録したレコードを参照してみる。

>> prefs["Shimaneken"]
=> #<Groonga::Record:0x007f9fe671a1f0 ..., attributes: {"_id"=>32, "_key"=>"Shimaneken", "pref_name"=>"島根県"}>

>> prefs["Shimaneken"].id
=> 32

>> prefs["Shimaneken"].key
=> "Shimaneken"

>> prefs["Shimaneken"].pref_name
=> "島根県"

>> prefs.size
=> 47

6. 全文検索用語彙テーブルの作成

全文検索用語彙テーブルを作成する。(以下は、テーブルタイプを PatriciaTrie に、ノーマライザを大文字小文字の区別をしない NormalizerAuto に、デフォルトトークナイザを N-gram の一種バイグラムに設定する例)

>> Groonga::Schema.create_table("Terms",
 |   :type => :patricia_trie,
 |   :normalizer => :NormalizerAuto,
 | :default_tokenizer => "TokenBigram")
=> [#<Groonga::Schema::TableDefinition:0x007f9fe6bb9cb0
  @definitions=[],
  @name="Terms",
  @options=
   {:context=>
     #<Groonga::Context encoding: <:utf8>, database: <#<Groonga::Database id: <nil>, name: (anonymous), path: </path/to/prefs.db>, domain: (nil), range: (nil), flags: <>>>>,
    :type=>:patricia_trie,
    :normalizer=>:NormalizerAuto,
    :default_tokenizer=>"TokenBigram"},
  @table_type=Groonga::PatriciaTrie>]

7. 全文検索用語彙テーブルのインデックス定義

今回は都道府県名ローマ字で検索してみることにする。

>> Groonga::Schema.change_table("Terms") do |tbl|
 |   tbl.index("Prefs.pref_name")
 | end
=> [#<Groonga::Schema::TableDefinition:0x007f9fe6a823d8
  @definitions=
   [#<Groonga::Schema::IndexColumnDefinition:0x007f9fe6a81d48
     @name=nil,
     @options={:persistent=>true, :named_path=>nil},
     @target_columns=["pref_name"],
     @target_table="Prefs">],
  @name="Terms",
  @options=
   {:context=>
     #<Groonga::Context encoding: <:utf8>, database: <#<Groonga::Database id: <nil>, name: (anonymous), path: </path/to/prefs.db>, domain: (nil), range: (nil), flags: <>>>>,
    :change=>true},
  @table_type=Groonga::Array>]

8. 検索の確認

>> prefs_shimane = prefs.select { |rec| rec.pref_name =~ "島根県" }    => #<Groonga::Hash id: <2147483655>, name: (anonymous), path: (temporary), domain: <Prefs>, range: (nil), flags: <WITH_SUBREC>, size: <1>, encoding: <:utf8>, default_tokenizer: (nil), token_filters: [], normalizer: (nil)>

>> prefs_shimane.size
=> 1

>> prefs_shimane.collect { |rec| rec.key.key }
=> ["Shimaneken"]

>> prefs_shimane.collect { |rec| rec["_key"] }
=> ["Shimaneken"]

9. 参考サイト


その他の詳細な使用方法は実際に Ruby コーディングしながら覚えることになるでしょう。

以上。





 

Sponsored Link

 

Comments