Skip to content

Instantly share code, notes, and snippets.

@jugyo
Created August 15, 2012 07:35
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jugyo/3357397 to your computer and use it in GitHub Desktop.
Save jugyo/3357397 to your computer and use it in GitHub Desktop.
Groonga + Ruby で全文検索

Groonga + Ruby で全文検索

groonga のインストール

$ brew install groonga

rroonga のインストール

Ruby から groonga を使うために rroonga というライブラリを使う:

$ gem install rroonga

サンプルアプリ

ブログっぽいデータ構造を作ってそれを検索できるようにしてみる。

$ irb -rgroonga

デフォルトの文字コードを指定:

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

データベースの作成:

Groonga::Database.create(:path => "/tmp/blog.db")

スキーマの定義:

Groonga::Schema.create_table("Entries") do |table|
  table.short_text("title")
  table.text("content")
end

全文検索用のテーブルを作成:

Groonga::Schema.create_table("Terms",
  type: :patricia_trie,
  key_normalize: true,
  default_tokenizer: "TokenBigram"
) do |table|
  table.index("Entries.content")
end

table.index("Entries.content") としているところがポイント。なんか、こうするらしい。 key_normalize: true で大文字と小文字を区別しないように、 default_tokenizer: "TokenBigram" でトークナイザとしてバイグラムを指定している。 type: :patricia_trie というのはえーと、何だろうねぇ。

適当なデータをいくつか追加:

Groonga["Entries"].add(title: 'たのしいRuby', content: 'Rubyはたのしい')
Groonga["Entries"].add(title: '今日の晩ご飯', content: '今日の晩ご飯はカレー')

検索:

entries = Groonga["Entries"].select {|i| i.content =~ 'ruby'}
entries.each do |entry|
  puts "#{entry.title}: #{entry.content}"
end

以下が出力されれば成功:

たのしいRuby: Rubyはたのしい

参考

@kou
Copy link

kou commented Aug 15, 2012

type: :patricia_trie というのはえーと、何だろうねぇ。

パトリシアトライ という木構造なデータ構造でテーブルのキーを管理する!という意味です!

パトリシアトライ以外にもハッシュテーブルでキーを管理することもできます。ハッシュテーブルだと完全一致するキーしか見つけることができないのですが、パトリシアトライだと前方一致や最長共通接頭辞検索(Longest Common Prefix Search)でキーを見つけたりもできてキーの検索機能が豊富になります。で、どういうことができるようになるかというと、例えば、はてなキーワードのオートリンクみたいなことができるようになります。

http://groonga.rubyforge.org/rroonga/ja/Groonga/PatriciaTrie.html#tag_keys-instance_method

@jugyo
Copy link
Author

jugyo commented Aug 15, 2012

なるほど!勉強になります!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment